diff --git a/app/code/Magento/Bundle/Model/Plugin/Frontend/Product.php b/app/code/Magento/Bundle/Model/Plugin/Frontend/Product.php
new file mode 100644
index 0000000000000..499f0cd2ca9c5
--- /dev/null
+++ b/app/code/Magento/Bundle/Model/Plugin/Frontend/Product.php
@@ -0,0 +1,48 @@
+type = $type;
+ }
+
+ /**
+ * Add child identities to product identities
+ *
+ * @param CatalogProduct $product
+ * @param array $identities
+ * @return array
+ */
+ public function afterGetIdentities(CatalogProduct $product, array $identities): array
+ {
+ foreach ($this->type->getChildrenIds($product->getEntityId()) as $childIds) {
+ foreach ($childIds as $childId) {
+ $identities[] = CatalogProduct::CACHE_TAG . '_' . $childId;
+ }
+ }
+
+ return array_unique($identities);
+ }
+}
diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Plugin/Frontend/ProductTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Plugin/Frontend/ProductTest.php
new file mode 100644
index 0000000000000..ee08618eab5dd
--- /dev/null
+++ b/app/code/Magento/Bundle/Test/Unit/Model/Plugin/Frontend/ProductTest.php
@@ -0,0 +1,73 @@
+product = $this->getMockBuilder(Product::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getEntityId'])
+ ->getMock();
+
+ $this->type = $this->getMockBuilder(Type::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getChildrenIds'])
+ ->getMock();
+
+ $this->plugin = new ProductPlugin($this->type);
+ }
+
+ public function testAfterGetIdentities()
+ {
+ $baseIdentities = [
+ 'SomeCacheId',
+ 'AnotherCacheId',
+ ];
+ $id = 12345;
+ $childIds = [
+ 1 => [1, 2, 5, 100500],
+ 12 => [7, 22, 45, 24612]
+ ];
+ $expectedIdentities = [
+ 'SomeCacheId',
+ 'AnotherCacheId',
+ Product::CACHE_TAG . '_' . 1,
+ Product::CACHE_TAG . '_' . 2,
+ Product::CACHE_TAG . '_' . 5,
+ Product::CACHE_TAG . '_' . 100500,
+ Product::CACHE_TAG . '_' . 7,
+ Product::CACHE_TAG . '_' . 22,
+ Product::CACHE_TAG . '_' . 45,
+ Product::CACHE_TAG . '_' . 24612,
+ ];
+ $this->product->expects($this->once())
+ ->method('getEntityId')
+ ->will($this->returnValue($id));
+ $this->type->expects($this->once())
+ ->method('getChildrenIds')
+ ->with($id)
+ ->will($this->returnValue($childIds));
+ $identities = $this->plugin->afterGetIdentities($this->product, $baseIdentities);
+ $this->assertEquals($expectedIdentities, $identities);
+ }
+}
diff --git a/app/code/Magento/Bundle/etc/frontend/di.xml b/app/code/Magento/Bundle/etc/frontend/di.xml
index 54f6d3b4b0f42..fc820ff87a129 100644
--- a/app/code/Magento/Bundle/etc/frontend/di.xml
+++ b/app/code/Magento/Bundle/etc/frontend/di.xml
@@ -13,4 +13,7 @@
+
+
+
diff --git a/app/code/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtender.php b/app/code/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtender.php
new file mode 100644
index 0000000000000..92b7ab0d88ea8
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtender.php
@@ -0,0 +1,48 @@
+configurableType = $configurableType;
+ }
+
+ /**
+ * Add child identities to product identities
+ *
+ * @param Product $subject
+ * @param array $identities
+ * @return array
+ */
+ public function afterGetIdentities(Product $subject, array $identities): array
+ {
+ foreach ($this->configurableType->getChildrenIds($subject->getId()) as $childIds) {
+ foreach ($childIds as $childId) {
+ $identities[] = Product::CACHE_TAG . '_' . $childId;
+ }
+ }
+
+ return array_unique($identities);
+ }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php
new file mode 100644
index 0000000000000..b4fb5ccfaa558
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php
@@ -0,0 +1,77 @@
+product = $this->getMockBuilder(Product::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getId'])
+ ->getMock();
+
+ $this->configurableTypeMock = $this->getMockBuilder(Configurable::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->plugin = new ProductIdentitiesExtender($this->configurableTypeMock);
+ }
+
+ public function testAfterGetIdentities()
+ {
+ $identities = [
+ 'SomeCacheId',
+ 'AnotherCacheId',
+ ];
+ $productId = 12345;
+ $childIdentities = [
+ 0 => [1, 2, 5, 100500]
+ ];
+ $expectedIdentities = [
+ 'SomeCacheId',
+ 'AnotherCacheId',
+ Product::CACHE_TAG . '_' . 1,
+ Product::CACHE_TAG . '_' . 2,
+ Product::CACHE_TAG . '_' . 5,
+ Product::CACHE_TAG . '_' . 100500,
+ ];
+
+ $this->product->expects($this->once())
+ ->method('getId')
+ ->willReturn($productId);
+
+ $this->configurableTypeMock->expects($this->once())
+ ->method('getChildrenIds')
+ ->with($productId)
+ ->willReturn($childIdentities);
+
+ $productIdentities = $this->plugin->afterGetIdentities($this->product, $identities);
+ $this->assertEquals($expectedIdentities, $productIdentities);
+ }
+}
diff --git a/app/code/Magento/ConfigurableProduct/etc/frontend/di.xml b/app/code/Magento/ConfigurableProduct/etc/frontend/di.xml
index bb830c36b929d..df96829b354c8 100644
--- a/app/code/Magento/ConfigurableProduct/etc/frontend/di.xml
+++ b/app/code/Magento/ConfigurableProduct/etc/frontend/di.xml
@@ -10,4 +10,7 @@
+
+
+
diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Model/Plugin/Frontend/ProductTest.php b/dev/tests/integration/testsuite/Magento/Bundle/Model/Plugin/Frontend/ProductTest.php
new file mode 100644
index 0000000000000..91dcd5f3e8d5b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Bundle/Model/Plugin/Frontend/ProductTest.php
@@ -0,0 +1,71 @@
+get(PluginList::class)
+ ->get(\Magento\Catalog\Model\Product::class, []);
+ $this->assertSame(Product::class, $pluginInfo['bundle']['instance']);
+ }
+
+ /**
+ * Check plugin will add children ids to bundle product identities on storefront.
+ *
+ * @magentoDataFixture Magento/Bundle/_files/product.php
+ * @magentoAppArea frontend
+ * @return void
+ */
+ public function testGetIdentitiesForBundleProductOnStorefront(): void
+ {
+ $productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
+ $bundleProduct = $productRepository->get('bundle-product');
+ $simpleProduct = $productRepository->get('simple');
+ $expectedIdentities = [
+ 'cat_p_' . $bundleProduct->getId(),
+ 'cat_p',
+ 'cat_p_' . $simpleProduct->getId(),
+
+ ];
+ $this->assertEquals($expectedIdentities, $bundleProduct->getIdentities());
+ }
+
+ /**
+ * Check plugin won't add children ids to bundle product identities in admin area.
+ *
+ * @magentoDataFixture Magento/Bundle/_files/product.php
+ * @magentoAppArea adminhtml
+ * @return void
+ */
+ public function testGetIdentitiesForBundleProductInAdminArea(): void
+ {
+ $productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
+ $bundleProduct = $productRepository->get('bundle-product');
+ $expectedIdentities = [
+ 'cat_p_' . $bundleProduct->getId(),
+ ];
+ $this->assertEquals($expectedIdentities, $bundleProduct->getIdentities());
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php
new file mode 100644
index 0000000000000..1fffd701c509f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php
@@ -0,0 +1,73 @@
+get(PluginList::class)
+ ->get(\Magento\Catalog\Model\Product::class, []);
+ $this->assertSame(ProductIdentitiesExtender::class, $pluginInfo['product_identities_extender']['instance']);
+ }
+
+ /**
+ * Check plugin will add children ids to configurable product identities on storefront.
+ *
+ * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+ * @magentoAppArea frontend
+ * @return void
+ */
+ public function testGetIdentitiesForConfigurableProductOnStorefront(): void
+ {
+ $productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
+ $configurableProduct = $productRepository->get('configurable');
+ $simpleProduct1 = $productRepository->get('simple_10');
+ $simpleProduct2 = $productRepository->get('simple_20');
+ $expectedIdentities = [
+ 'cat_p_' . $configurableProduct->getId(),
+ 'cat_p',
+ 'cat_p_' . $simpleProduct1->getId(),
+ 'cat_p_' . $simpleProduct2->getId(),
+
+ ];
+ $this->assertEquals($expectedIdentities, $configurableProduct->getIdentities());
+ }
+
+ /**
+ * Check plugin won't add children ids to configurable product identities in admin area.
+ *
+ * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+ * @magentoAppArea adminhtml
+ * @return void
+ */
+ public function testGetIdentitiesForConfigurableProductInAdminArea(): void
+ {
+ $productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
+ $configurableProduct = $productRepository->get('configurable');
+ $expectedIdentities = [
+ 'cat_p_' . $configurableProduct->getId(),
+ ];
+ $this->assertEquals($expectedIdentities, $configurableProduct->getIdentities());
+ }
+}