diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
index ef4423857e..ba8bbdb801 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
@@ -487,7 +487,8 @@ public function onDependencyRemoval(array $dependencies) {
    * already invalidates it.
    */
   protected function invalidateTagsOnSave($update) {
-    Cache::invalidateTags($this->getEntityType()->getListCacheTags());
+    $tags = Cache::mergeTags($this->getEntityType()->getListCacheTags(), $this->getListCacheTags());
+    Cache::invalidateTags($tags);
   }
 
   /**
@@ -497,7 +498,11 @@ protected function invalidateTagsOnSave($update) {
    * config system already invalidates them.
    */
   protected static function invalidateTagsOnDelete(EntityTypeInterface $entity_type, array $entities) {
-    Cache::invalidateTags($entity_type->getListCacheTags());
+    $tags = $entity_type->getListCacheTags();
+    foreach ($entities as $entity) {
+      $tags = Cache::mergeTags($tags, $entity->getListCacheTags());
+    }
+    Cache::invalidateTags($tags);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index 84991bc609..922b47da70 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -488,12 +488,23 @@ public function getCacheContexts() {
     return $this->cacheContexts;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getListCacheTags() {
+    $tags = $this->getEntityType()->getListCacheTags();
+    if ($this->bundle() != $this->entityTypeId) {
+      foreach ($tags as $key => $tag) {
+        $tags[$key] = $tag . ':' . $this->bundle();
+      }
+    }
+    return $tags;
+  }
+
   /**
    * {@inheritdoc}
    */
   public function getCacheTagsToInvalidate() {
-    // @todo Add bundle-specific listing cache tag?
-    //   https://www.drupal.org/node/2145751
     if ($this->isNew()) {
       return [];
     }
@@ -558,7 +569,7 @@ protected function invalidateTagsOnSave($update) {
     // updated entity may start to appear in a listing because it now meets that
     // listing's filtering requirements. A newly created entity may start to
     // appear in listings because it did not exist before.)
-    $tags = $this->getEntityType()->getListCacheTags();
+    $tags = $this->getListCacheTags();
     if ($this->hasLinkTemplate('canonical')) {
       // Creating or updating an entity may change a cached 403 or 404 response.
       $tags = Cache::mergeTags($tags, ['4xx-response']);
@@ -587,6 +598,7 @@ protected static function invalidateTagsOnDelete(EntityTypeInterface $entity_typ
       // cache tag, but subsequent list pages would not be invalidated, hence we
       // must invalidate its list cache tags as well.)
       $tags = Cache::mergeTags($tags, $entity->getCacheTagsToInvalidate());
+      $tags = Cache::mergeTags($tags, $entity->getListCacheTags());
     }
     Cache::invalidateTags($tags);
   }
diff --git a/core/lib/Drupal/Core/Entity/EntityInterface.php b/core/lib/Drupal/Core/Entity/EntityInterface.php
index 9cdb435f29..4dfa71a076 100644
--- a/core/lib/Drupal/Core/Entity/EntityInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityInterface.php
@@ -424,6 +424,16 @@ public function referencedEntities();
    */
   public function getOriginalId();
 
+  /**
+   * The list cache tags associated with this entity.
+   *
+   * Enables code listing entities of this type to ensure that newly created
+   * entities show up immediately.
+   *
+   * @return string[]
+   */
+  public function getListCacheTags();
+
   /**
    * Returns the cache tags that should be used to invalidate caches.
    *
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index da1a43bc16..9381eb6082 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -391,16 +391,18 @@ public function resetCache(array $entities = NULL) {
     // When we have a way to invalidate only those cache items that have both
     // the individual entity's cache tag and the view builder's cache tag, we'll
     // be able to optimize this further.
+    $tags = [];
     if (isset($entities)) {
-      $tags = [];
       foreach ($entities as $entity) {
         $tags = Cache::mergeTags($tags, $entity->getCacheTags());
-        $tags = Cache::mergeTags($tags, $entity->getEntityType()->getListCacheTags());
+        $tags = Cache::mergeTags($tags, $entity->getListCacheTags());
       }
       Cache::invalidateTags($tags);
     }
     else {
-      Cache::invalidateTags($this->getCacheTags());
+      $tags = Cache::mergeTags($tags, $this->getCacheTags());
+      $tags = Cache::mergeTags($tags, $this->entityType->getListCacheTags());
+      Cache::invalidateTags($tags);
     }
   }
 
diff --git a/core/modules/block/src/BlockViewBuilder.php b/core/modules/block/src/BlockViewBuilder.php
index 3b20d7b25c..a83430cee3 100644
--- a/core/modules/block/src/BlockViewBuilder.php
+++ b/core/modules/block/src/BlockViewBuilder.php
@@ -83,6 +83,7 @@ public function viewMultiple(array $entities = [], $view_mode = 'full', $langcod
       $plugin = $entity->getPlugin();
 
       $cache_tags = Cache::mergeTags($this->getCacheTags(), $entity->getCacheTags());
+      $cache_tags = Cache::mergeTags($cache_tags, $entity->getListCacheTags());
       $cache_tags = Cache::mergeTags($cache_tags, $plugin->getCacheTags());
 
       // Create the render array for the block as a whole.
diff --git a/core/modules/block/src/Entity/Block.php b/core/modules/block/src/Entity/Block.php
index ece8de38ab..9029c826cd 100644
--- a/core/modules/block/src/Entity/Block.php
+++ b/core/modules/block/src/Entity/Block.php
@@ -255,6 +255,18 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   *
+   * Block configuration entities are a special case: one block entity stores
+   * the placement of one block in one theme. Instead of using an entity type-
+   * specific list cache tag like most entities, use the cache tag of the theme
+   * this block is placed in instead.
+   */
+  public function getListCacheTags() {
+    return ['theme:' . $this->theme];
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/block/tests/src/Functional/BlockTest.php b/core/modules/block/tests/src/Functional/BlockTest.php
index 53b48662cd..f9ce0fcd5b 100644
--- a/core/modules/block/tests/src/Functional/BlockTest.php
+++ b/core/modules/block/tests/src/Functional/BlockTest.php
@@ -382,6 +382,7 @@ public function testBlockCacheTags() {
     $cache_entry = \Drupal::cache('page')->get($cid);
     $expected_cache_tags = [
       'config:block_list',
+      'theme:classy',
       'block_view',
       'config:block.block.powered',
       'config:user.role.anonymous',
@@ -396,6 +397,7 @@ public function testBlockCacheTags() {
       'block_view',
       'config:block.block.powered',
       'rendered',
+      'theme:classy',
     ];
     sort($expected_cache_tags);
     $this->assertIdentical($cache_entry->tags, $expected_cache_tags);
@@ -423,6 +425,7 @@ public function testBlockCacheTags() {
     $cache_entry = \Drupal::cache('page')->get($cid);
     $expected_cache_tags = [
       'config:block_list',
+      'theme:classy',
       'block_view',
       'config:block.block.powered',
       'config:block.block.powered-2',
@@ -436,6 +439,7 @@ public function testBlockCacheTags() {
       'block_view',
       'config:block.block.powered',
       'rendered',
+      'theme:classy',
     ];
     sort($expected_cache_tags);
     $keys = \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:language_interface', 'theme', 'user.permissions'])->getKeys();
@@ -445,6 +449,7 @@ public function testBlockCacheTags() {
       'block_view',
       'config:block.block.powered-2',
       'rendered',
+      'theme:classy',
     ];
     sort($expected_cache_tags);
     $keys = \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:language_interface', 'theme', 'user.permissions'])->getKeys();
diff --git a/core/modules/block/tests/src/Functional/Views/DisplayBlockTest.php b/core/modules/block/tests/src/Functional/Views/DisplayBlockTest.php
index cdb1998241..2bda2be5d3 100644
--- a/core/modules/block/tests/src/Functional/Views/DisplayBlockTest.php
+++ b/core/modules/block/tests/src/Functional/Views/DisplayBlockTest.php
@@ -269,7 +269,7 @@ public function testBlockRendering() {
     $result = $this->xpath('//div[contains(@class, "region-sidebar-first")]/div[contains(@class, "block-views")]/h2');
     $this->assertTrue(empty($result), 'The title is not visible.');
 
-    $this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'config:system.site', 'config:views.view.test_view_block', 'http_response', 'rendered']));
+    $this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'theme:classy', 'config:system.site', 'config:views.view.test_view_block', 'http_response', 'rendered']));
   }
 
   /**
@@ -295,7 +295,7 @@ public function testBlockEmptyRendering() {
     $this->assertEqual(0, count($this->xpath('//div[contains(@class, "block-views-blocktest-view-block-block-1")]')));
     // Ensure that the view cacheability metadata is propagated even, for an
     // empty block.
-    $this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'config:views.view.test_view_block', 'http_response', 'rendered']));
+    $this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'theme:classy', 'config:views.view.test_view_block', 'http_response', 'rendered']));
     $this->assertCacheContexts(['url.query_args:_wrapper_format']);
 
     // Add a header displayed on empty result.
@@ -313,7 +313,7 @@ public function testBlockEmptyRendering() {
 
     $this->drupalGet($url);
     $this->assertEqual(1, count($this->xpath('//div[contains(@class, "block-views-blocktest-view-block-block-1")]')));
-    $this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'config:views.view.test_view_block', 'http_response', 'rendered']));
+    $this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'theme:classy', 'config:views.view.test_view_block', 'http_response', 'rendered']));
     $this->assertCacheContexts(['url.query_args:_wrapper_format']);
 
     // Hide the header on empty results.
@@ -331,7 +331,7 @@ public function testBlockEmptyRendering() {
 
     $this->drupalGet($url);
     $this->assertEqual(0, count($this->xpath('//div[contains(@class, "block-views-blocktest-view-block-block-1")]')));
-    $this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'config:views.view.test_view_block', 'http_response', 'rendered']));
+    $this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'theme:classy', 'config:views.view.test_view_block', 'http_response', 'rendered']));
     $this->assertCacheContexts(['url.query_args:_wrapper_format']);
 
     // Add an empty text.
@@ -348,7 +348,7 @@ public function testBlockEmptyRendering() {
 
     $this->drupalGet($url);
     $this->assertEqual(1, count($this->xpath('//div[contains(@class, "block-views-blocktest-view-block-block-1")]')));
-    $this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'config:views.view.test_view_block', 'http_response', 'rendered']));
+    $this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'theme:classy', 'config:views.view.test_view_block', 'http_response', 'rendered']));
     $this->assertCacheContexts(['url.query_args:_wrapper_format']);
   }
 
diff --git a/core/modules/block/tests/src/Kernel/BlockViewBuilderTest.php b/core/modules/block/tests/src/Kernel/BlockViewBuilderTest.php
index 71c4f55b8d..5a44c1b1dd 100644
--- a/core/modules/block/tests/src/Kernel/BlockViewBuilderTest.php
+++ b/core/modules/block/tests/src/Kernel/BlockViewBuilderTest.php
@@ -223,7 +223,7 @@ public function testBlockViewBuilderBuildAlter() {
 
     $default_keys = ['entity_view', 'block', 'test_block'];
     $default_contexts = [];
-    $default_tags = ['block_view', 'config:block.block.test_block'];
+    $default_tags = ['block_view', 'config:block.block.test_block', 'theme:stark'];
     $default_max_age = Cache::PERMANENT;
 
     // hook_block_build_alter() adds an additional cache key.
diff --git a/core/modules/block_content/tests/src/Functional/BlockContentCacheTagsTest.php b/core/modules/block_content/tests/src/Functional/BlockContentCacheTagsTest.php
index ea5dd2873d..0159d01fe4 100644
--- a/core/modules/block_content/tests/src/Functional/BlockContentCacheTagsTest.php
+++ b/core/modules/block_content/tests/src/Functional/BlockContentCacheTagsTest.php
@@ -88,6 +88,7 @@ public function testBlock() {
     $expected_block_cache_keys = ['entity_view', 'block', $block->id()];
     $expected_block_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'];
     $expected_block_cache_tags = Cache::mergeTags(['block_view', 'rendered'], $block->getCacheTags());
+    $expected_block_cache_tags = Cache::mergeTags($expected_block_cache_tags, $block->getListCacheTags());
     $expected_block_cache_tags = Cache::mergeTags($expected_block_cache_tags, $block->getPlugin()->getCacheTags());
 
     // Expected contexts and tags for the BlockContent entity.
diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index b5d5515969..6206b10008 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -240,7 +240,7 @@ function book_node_view(array &$build, EntityInterface $node, EntityViewDisplayI
         // The book navigation is a listing of Node entities, so associate its
         // list cache tag for correct invalidation.
         '#cache' => [
-          'tags' => $node->getEntityType()->getListCacheTags(),
+          'tags' => $node->getListCacheTags(),
         ],
       ];
     }
diff --git a/core/modules/book/src/BookExport.php b/core/modules/book/src/BookExport.php
index a323370051..953916878f 100644
--- a/core/modules/book/src/BookExport.php
+++ b/core/modules/book/src/BookExport.php
@@ -80,7 +80,7 @@ public function bookExportHtml(NodeInterface $node) {
       '#contents' => $contents,
       '#depth' => $node->book['depth'],
       '#cache' => [
-        'tags' => $node->getEntityType()->getListCacheTags(),
+        'tags' => $node->getListCacheTags(),
       ],
     ];
   }
diff --git a/core/modules/menu_ui/tests/src/Functional/MenuCacheTagsTest.php b/core/modules/menu_ui/tests/src/Functional/MenuCacheTagsTest.php
index c0d36690bc..6802aed567 100644
--- a/core/modules/menu_ui/tests/src/Functional/MenuCacheTagsTest.php
+++ b/core/modules/menu_ui/tests/src/Functional/MenuCacheTagsTest.php
@@ -50,6 +50,7 @@ public function testMenuBlock() {
       'rendered',
       'block_view',
       'config:block_list',
+      'theme:classy',
       'config:block.block.' . $block->id(),
       'config:system.menu.llama',
       // The cache contexts associated with the (in)accessible menu links are
diff --git a/core/modules/page_cache/tests/src/Functional/PageCacheTagsIntegrationTest.php b/core/modules/page_cache/tests/src/Functional/PageCacheTagsIntegrationTest.php
index 952ad623f6..68a0c7ad4c 100644
--- a/core/modules/page_cache/tests/src/Functional/PageCacheTagsIntegrationTest.php
+++ b/core/modules/page_cache/tests/src/Functional/PageCacheTagsIntegrationTest.php
@@ -88,6 +88,7 @@ public function testPageCacheTags() {
       'block_view',
       'local_task',
       'config:block_list',
+      'theme:bartik',
       'config:block.block.bartik_branding',
       'config:block.block.bartik_breadcrumbs',
       'config:block.block.bartik_content',
@@ -130,6 +131,7 @@ public function testPageCacheTags() {
       'block_view',
       'local_task',
       'config:block_list',
+      'theme:bartik',
       'config:block.block.bartik_branding',
       'config:block.block.bartik_breadcrumbs',
       'config:block.block.bartik_content',
diff --git a/core/modules/shortcut/src/Entity/Shortcut.php b/core/modules/shortcut/src/Entity/Shortcut.php
index 92e59fb53f..82b67cb6e7 100644
--- a/core/modules/shortcut/src/Entity/Shortcut.php
+++ b/core/modules/shortcut/src/Entity/Shortcut.php
@@ -160,6 +160,13 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     return $fields;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getListCacheTags() {
+    return $this->shortcut_set->entity->getListCacheTags();
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php b/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php
index 0f169238c6..442cf52d13 100644
--- a/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php
+++ b/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php
@@ -50,7 +50,7 @@ public function testPopularContentBlock() {
 
     $tags = Cache::mergeTags($node->getCacheTags(), $block->getCacheTags());
     $tags = Cache::mergeTags($tags, $this->blockingUser->getCacheTags());
-    $tags = Cache::mergeTags($tags, ['block_view', 'config:block_list', 'node_list', 'rendered', 'user_view']);
+    $tags = Cache::mergeTags($tags, ['block_view', 'config:block_list', 'theme:classy', 'node_list', 'rendered', 'user_view']);
     $this->assertCacheTags($tags);
     $contexts = Cache::mergeContexts($node->getCacheContexts(), $block->getCacheContexts());
     $contexts = Cache::mergeContexts($contexts, ['url.query_args:_wrapper_format']);
diff --git a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
index 517e1c670e..1969350a37 100644
--- a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
+++ b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
@@ -381,9 +381,9 @@ public function testReferencedEntity() {
     // Generate the cache tags for all two possible entity listing paths.
     // 1. list cache tag only (listing query has no match)
     // 2. list cache tag plus entity cache tag (listing query has a match)
-    $empty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $page_cache_tags);
+    $empty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getListCacheTags(), $page_cache_tags);
 
-    $nonempty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $this->entity->getCacheTags());
+    $nonempty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getListCacheTags(), $this->entity->getCacheTags());
     $nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $this->getAdditionalCacheTagsForEntityListing($this->entity));
     $nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $page_cache_tags);
 
@@ -524,7 +524,7 @@ public function testReferencedEntity() {
       $this->verifyPageCache($non_referencing_entity_url, 'HIT');
       // Special case: entity types may choose to use their bundle entity type
       // cache tags, to avoid having excessively granular invalidation.
-      $is_special_case = $bundle_entity->getCacheTags() == $this->entity->getCacheTags() && $bundle_entity->getEntityType()->getListCacheTags() == $this->entity->getEntityType()->getListCacheTags();
+      $is_special_case = $bundle_entity->getCacheTags() == $this->entity->getCacheTags() && $bundle_entity->getListCacheTags() == $this->entity->getListCacheTags();
       if ($is_special_case) {
         $this->verifyPageCache($empty_entity_listing_url, 'MISS');
         $this->verifyPageCache($nonempty_entity_listing_url, 'MISS');
@@ -597,7 +597,7 @@ public function testReferencedEntity() {
     // there is a cache miss for both the empty entity listing and the non-empty
     // entity listing routes, but not for other routes.
     $this->pass("Test invalidation of referenced entity's list cache tag.", 'Debug');
-    Cache::invalidateTags($this->entity->getEntityType()->getListCacheTags());
+    Cache::invalidateTags($this->entity->getListCacheTags());
     $this->verifyPageCache($empty_entity_listing_url, 'MISS');
     $this->verifyPageCache($nonempty_entity_listing_url, 'MISS');
     $this->verifyPageCache($referencing_entity_url, 'HIT');
@@ -639,7 +639,7 @@ public function testReferencedEntity() {
     $referencing_entity_cache_tags = Cache::mergeTags($this->referencingEntity->getCacheTags(), \Drupal::entityManager()->getViewBuilder('entity_test')->getCacheTags());
     $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, ['http_response', 'rendered']);
 
-    $nonempty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $this->getAdditionalCacheTagsForEntityListing());
+    $nonempty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getListCacheTags(), $this->getAdditionalCacheTagsForEntityListing());
     $nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $page_cache_tags);
 
     $this->verifyPageCache($referencing_entity_url, 'HIT', Cache::mergeTags($referencing_entity_cache_tags, $page_cache_tags));
diff --git a/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php b/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php
index fa69e783d0..8a96049060 100644
--- a/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php
+++ b/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php
@@ -78,11 +78,8 @@ public function listEntitiesAlphabetically($entity_type_id) {
     foreach ($entities as $entity) {
       $labels[] = $entity->label();
       $cache_tags = Cache::mergeTags($cache_tags, $entity->getCacheTags());
+      $cache_tags = Cache::mergeTags($cache_tags, $entity->getListCacheTags());
     }
-    // Always associate the list cache tag, otherwise the cached empty result
-    // wouldn't be invalidated. This would continue to show nothing matches the
-    // query, even though a newly created entity might match the query.
-    $cache_tags = Cache::mergeTags($cache_tags, $entity_type_definition->getListCacheTags());
 
     return [
       '#theme' => 'item_list',
diff --git a/core/modules/system/tests/src/Functional/Entity/EntityCacheTagsTestBase.php b/core/modules/system/tests/src/Functional/Entity/EntityCacheTagsTestBase.php
index 447afbfa76..7166929fe3 100644
--- a/core/modules/system/tests/src/Functional/Entity/EntityCacheTagsTestBase.php
+++ b/core/modules/system/tests/src/Functional/Entity/EntityCacheTagsTestBase.php
@@ -319,6 +319,7 @@ protected function createReferenceTestEntities($referenced_entity) {
    * - entity type view cache tag: "<entity type>_view"
    * - entity cache tag: "<entity type>:<entity ID>"
    * - entity type list cache tag: "<entity type>_list"
+   * - entity type list cache tag: "<entity type>_list:<entity bundle>"
    * - referencing entity type view cache tag: "<referencing entity type>_view"
    * - referencing entity type cache tag: "<referencing entity type>:<referencing entity ID>"
    */
@@ -376,7 +377,7 @@ public function testReferencedEntity() {
     // 2. list cache tag plus entity cache tag (listing query has a match)
     $empty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $page_cache_tags);
 
-    $nonempty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $this->entity->getCacheTags());
+    $nonempty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getListCacheTags(), $this->entity->getCacheTags());
     $nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $this->getAdditionalCacheTagsForEntityListing($this->entity));
     $nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $page_cache_tags);
 
@@ -445,7 +446,7 @@ public function testReferencedEntity() {
     $this->entity->save();
     $this->verifyPageCache($referencing_entity_url, 'MISS');
     $this->verifyPageCache($listing_url, 'MISS');
-    $this->verifyPageCache($empty_entity_listing_url, 'MISS');
+    $this->verifyPageCache($empty_entity_listing_url, 'HIT');
     $this->verifyPageCache($nonempty_entity_listing_url, 'MISS');
     $this->verifyPageCache($non_referencing_entity_url, 'HIT');
 
@@ -592,6 +593,7 @@ public function testReferencedEntity() {
     $this->pass("Test invalidation of referenced entity's list cache tag.", 'Debug');
     Cache::invalidateTags($this->entity->getEntityType()->getListCacheTags());
     $this->verifyPageCache($empty_entity_listing_url, 'MISS');
+    Cache::invalidateTags($this->entity->getListCacheTags());
     $this->verifyPageCache($nonempty_entity_listing_url, 'MISS');
     $this->verifyPageCache($referencing_entity_url, 'HIT');
     $this->verifyPageCache($non_referencing_entity_url, 'HIT');
diff --git a/core/modules/tracker/tests/src/Functional/TrackerTest.php b/core/modules/tracker/tests/src/Functional/TrackerTest.php
index bd13151c77..846529d0a8 100644
--- a/core/modules/tracker/tests/src/Functional/TrackerTest.php
+++ b/core/modules/tracker/tests/src/Functional/TrackerTest.php
@@ -98,10 +98,11 @@ public function testTrackerAll() {
       'config:block.block.page_actions_block',
       'config:block.block.page_tabs_block',
       'config:block_list',
+      'theme:classy',
     ];
     $expected_tags = Cache::mergeTags($expected_tags, $block_tags);
     $additional_tags = [
-      'node_list',
+      'node_list:page',
       'rendered',
     ];
     $expected_tags = Cache::mergeTags($expected_tags, $additional_tags);
@@ -185,10 +186,11 @@ public function testTrackerUser() {
       'config:block.block.page_actions_block',
       'config:block.block.page_tabs_block',
       'config:block_list',
+      'theme:classy',
     ];
     $expected_tags = Cache::mergeTags($expected_tags, $block_tags);
     $additional_tags = [
-      'node_list',
+      'node_list:page',
       'rendered',
     ];
     $expected_tags = Cache::mergeTags($expected_tags, $additional_tags);
diff --git a/core/modules/tracker/tracker.pages.inc b/core/modules/tracker/tracker.pages.inc
index 9093776de2..e43d410fc9 100644
--- a/core/modules/tracker/tracker.pages.inc
+++ b/core/modules/tracker/tracker.pages.inc
@@ -117,14 +117,19 @@ function tracker_page($account = NULL) {
 
       // Add node and node owner to cache tags.
       $cache_tags = Cache::mergeTags($cache_tags, $node->getCacheTags());
+      // Add the list cache tag for the node.
+      $cache_tags = Cache::mergeTags($cache_tags, $node->getListCacheTags());
       if ($node->getOwner()) {
         $cache_tags = Cache::mergeTags($cache_tags, $node->getOwner()->getCacheTags());
       }
     }
   }
-
-  // Add the list cache tag for nodes.
-  $cache_tags = Cache::mergeTags($cache_tags, \Drupal::entityManager()->getDefinition('node')->getListCacheTags());
+  else {
+    // Add empty list cache tag for nodes.
+    $cache_tags = Cache::mergeTags($cache_tags, \Drupal::entityManager()
+      ->getDefinition('node')
+      ->getListCacheTags());
+  }
 
   $page['tracker'] = [
     '#rows' => $rows,
diff --git a/core/modules/views/src/Plugin/views/cache/CachePluginBase.php b/core/modules/views/src/Plugin/views/cache/CachePluginBase.php
index 280ccf4d16..88074a5a73 100644
--- a/core/modules/views/src/Plugin/views/cache/CachePluginBase.php
+++ b/core/modules/views/src/Plugin/views/cache/CachePluginBase.php
@@ -241,6 +241,7 @@ public function getCacheTags() {
     if (!empty($entity_information)) {
       // Add the list cache tags for each entity type used by this view.
       foreach ($entity_information as $table => $metadata) {
+        // @todo add entity bundle specific cache tags.
         $tags = Cache::mergeTags($tags, \Drupal::entityManager()->getDefinition($metadata['entity_type'])->getListCacheTags());
       }
     }
@@ -316,6 +317,7 @@ public function getRowCacheTags(ResultRow $row) {
     if (!empty($row->_relationship_entities)) {
       foreach ($row->_relationship_entities as $entity) {
         $tags = Cache::mergeTags($tags, $entity->getCacheTags());
+        $tags = Cache::mergeTags($tags, $entity->getListCacheTags());
       }
     }
 
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index de323bd277..21a52e2cae 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -1337,6 +1337,13 @@ public function mergeCacheMaxAge($max_age) {
     return $this->storage->mergeCacheMaxAge($max_age);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getListCacheTags() {
+    return $this->storage->getListCacheTags();
+  }
+
   /**
    * {@inheritdoc}
    */
