diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index 6d41d13..98b616a 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -735,12 +735,12 @@ public function changed() {
     );
 
     foreach ($this->referencedEntities() as $referenced_entity) {
-      $referenced_entity_ids[$referenced_entity->entityType()][$referenced_entity->id()] = TRUE;
+      $referenced_entity_ids[$referenced_entity->entityType()][$referenced_entity->id()] = $referenced_entity;
     }
 
-    foreach ($referenced_entity_ids as $entity_type => $entity_ids) {
+    foreach ($referenced_entity_ids as $entity_type => $entities) {
       if (\Drupal::entityManager()->hasController($entity_type, 'render')) {
-        \Drupal::entityManager()->getRenderController($entity_type)->resetCache(array_keys($entity_ids));
+        \Drupal::entityManager()->getRenderController($entity_type)->resetCache($entities);
       }
     }
   }
diff --git a/core/lib/Drupal/Core/Entity/EntityRenderController.php b/core/lib/Drupal/Core/Entity/EntityRenderController.php
index fe6bd10..b12bd05 100644
--- a/core/lib/Drupal/Core/Entity/EntityRenderController.php
+++ b/core/lib/Drupal/Core/Entity/EntityRenderController.php
@@ -232,11 +232,12 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
   /**
    * {@inheritdoc}
    */
-  public function resetCache(array $ids = NULL) {
+  public function resetCache(array $entities = NULL) {
     if (isset($ids)) {
       $tags = array();
-      foreach ($ids as $entity_id) {
-        $tags[$this->entityType][$entity_id] = $entity_id;
+      foreach ($entities as $entity) {
+        $tags[$this->entityType][$entity->id()] = $entity->id();
+        $tags[$this->entityType . '_view_' . $entity->bundle()] = TRUE;
       }
       \Drupal::cache($this->cacheBin)->deleteTags($tags);
     }
diff --git a/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php b/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php
index a112fc2..2999944 100644
--- a/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php
@@ -79,10 +79,9 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
   /**
    * Resets the entity render cache.
    *
-   * @param array|null $ids
-   *   (optional) If specified, the cache is reset for the given entity IDs
-   *   only.
+   * @param array|null $entities
+   *   (optional) If specified, the cache is reset for the given entities  only.
    */
-  public function resetCache(array $ids = NULL);
+  public function resetCache(array $entities = NULL);
 
 }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php
index d6e1c45..bcf4274 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php
@@ -7,8 +7,8 @@
 
 namespace Drupal\views\Plugin\views\cache;
 
+use Drupal\Core\Cache\Cache;
 use Drupal\Core\Language\Language;
-use Drupal\views\ViewExecutable;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\views\Plugin\views\PluginBase;
 use Drupal\Core\Database\Query\Select;
@@ -109,7 +109,6 @@ protected function cacheSetExpire($type) {
     return CacheBackendInterface::CACHE_PERMANENT;
   }
 
-
   /**
    * Save data to the cache.
    *
@@ -126,17 +125,16 @@ public function cacheSet($type) {
           'total_rows' => isset($this->view->total_rows) ? $this->view->total_rows : 0,
           'current_page' => $this->view->getCurrentPage(),
         );
-        cache($this->table)->set($this->generateResultsKey(), $data, $this->cacheSetExpire($type));
+        \Drupal::cache($this->table)->set($this->generateResultsKey(), $data, $this->cacheSetExpire($type), $this->getCacheTags());
         break;
       case 'output':
         $this->storage['output'] = $this->view->display_handler->output;
         $this->gatherHeaders();
-        cache($this->table)->set($this->generateOutputKey(), $this->storage, $this->cacheSetExpire($type));
+        \Drupal::cache($this->table)->set($this->generateOutputKey(), $this->storage, $this->cacheSetExpire($type), $this->getCacheTags());
         break;
     }
   }
 
-
   /**
    * Retrieve data from the cache.
    *
@@ -151,7 +149,7 @@ public function cacheGet($type) {
       case 'results':
         // Values to set: $view->result, $view->total_rows, $view->execute_time,
         // $view->current_page.
-        if ($cache = cache($this->table)->get($this->generateResultsKey())) {
+        if ($cache = \Drupal::cache($this->table)->get($this->generateResultsKey())) {
           if (!$cutoff || $cache->created > $cutoff) {
             $this->view->result = $cache->data['result'];
             $this->view->total_rows = $cache->data['total_rows'];
@@ -162,7 +160,7 @@ public function cacheGet($type) {
         }
         return FALSE;
       case 'output':
-        if ($cache = cache($this->table)->get($this->generateOutputKey())) {
+        if ($cache = \Drupal::cache($this->table)->get($this->generateOutputKey())) {
           if (!$cutoff || $cache->created > $cutoff) {
             $this->storage = $cache->data;
             $this->view->display_handler->output = $cache->data['output'];
@@ -181,7 +179,7 @@ public function cacheGet($type) {
    * to be sure that we catch everything. Maybe that's a bad idea.
    */
   public function cacheFlush() {
-    cache($this->table)->deleteTags(array($this->view->storage->id() => TRUE));
+    Cache::invalidateTags(array($this->view->storage->id() => TRUE));
   }
 
   /**
@@ -327,6 +325,38 @@ public function generateOutputKey() {
     return $this->outputKey;
   }
 
+  /**
+   * Gets an array of cache tags for the current view.
+   *
+   * @return array
+   *   An array fo cache tags based on the current view.
+   */
+  protected function getCacheTags() {
+    $tags = array();
+    $entity_types = $this->view->getEntityTypes();
+
+    if (!empty($entity_types)) {
+      $tags[$this->view->storage->id()] = TRUE;
+      // Add an ENTIY_TYPE_view tag for each entity type used by this view.
+      foreach ($entity_types as $type) {
+        $tags[$type . '_view'] = TRUE;
+      }
+
+      // Collect entity IDs too if there are view results.
+      if (!empty($this->view->result)) {
+        foreach ($this->view->result as $result) {
+          $tags[$result->_entity->entityType()][] = $result->_entity->id();
+
+          foreach ($result->_relationship_entities as $entity) {
+            $tags[$entity->entityType()][] = $entity->id();
+          }
+        }
+      }
+    }
+
+    return $tags;
+  }
+
 }
 
 /**
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/cache/Tag.php b/core/modules/views/lib/Drupal/views/Plugin/views/cache/Tag.php
new file mode 100644
index 0000000..4cad30b
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/cache/Tag.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Plugin\views\cache\Tag.
+ */
+
+namespace Drupal\views\Plugin\views\cache;
+
+/**
+ * Simple caching of query results for Views displays.
+ *
+ * @ingroup views_cache_plugins
+ *
+ * @ViewsCache(
+ *   id = "tag",
+ *   title = @Translation("Tag based"),
+ *   help = @Translation("Tag based caching of data. Caches will persist until any related cache tags are invalidated.")
+ * )
+ */
+class Tag extends CachePluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function summaryTitle() {
+    return t('Tag');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function cacheExpire($type) {
+    return FALSE;
+  }
+
+}
diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php b/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php
index 54ac900..b85f3e3 100644
--- a/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php
@@ -2,11 +2,12 @@
 
 /**
  * @file
- * Contains \Drupal\views\Tests\ViewExecutableUnitTest.
+ * Contains \Drupal\views\Tests\ViewExecutableTest.
  */
 
 namespace Drupal\views\Tests;
 
+use Drupal\views\Views;
 use Drupal\views\ViewExecutable;
 use Drupal\views\ViewExecutableFactory;
 use Drupal\views\DisplayBag;
@@ -35,7 +36,7 @@ class ViewExecutableTest extends ViewUnitTestBase {
    *
    * @var array
    */
-  public static $testViews = array('test_destroy', 'test_executable_displays');
+  public static $testViews = array('test_destroy', 'test_executable_displays', 'test_view');
 
   /**
    * Properties that should be stored in the configuration.
@@ -433,4 +434,16 @@ public function testValidate() {
     $this->assertNotIdentical($validate, $validate_deleted, 'Master display has not been validated.');
   }
 
+  /**
+   * Tests the getEntityTypes() method.
+   */
+  public function testGetEntityTypes() {
+    // Test a view that should return no entity types.
+    $view = Views::getView('test_view');
+    $this->assertIdentical($view->getEntityTypes(), array(), 'No entity types were returned.');
+    // The base entity type (node) and relationships should be returned.
+    $view = Views::getView('test_destroy');
+    $this->assertIdentical($view->getEntityTypes(), array('node', 'comment', 'user'), 'The expected entity types were returned.');
+  }
+
 }
diff --git a/core/modules/views/lib/Drupal/views/ViewExecutable.php b/core/modules/views/lib/Drupal/views/ViewExecutable.php
index d8236cf..45cffaf 100644
--- a/core/modules/views/lib/Drupal/views/ViewExecutable.php
+++ b/core/modules/views/lib/Drupal/views/ViewExecutable.php
@@ -2225,4 +2225,34 @@ public function buildThemeFunctions($hook) {
     return $themes;
   }
 
+  /**
+   * Returns an array of all entity types used by this view.
+   *
+   * @return array
+   *   An array of entity types.
+   */
+  public function getEntityTypes() {
+    // Initialize handlers so we will have any relationships
+    $this->initHandlers();
+    // Start with the base table.
+    $entity_types = array();
+    $views_data = Views::viewsData();
+
+    // Add the base table.
+    $base_table_data = $views_data->get($this->storage->get('base_table'));
+    if (isset($base_table_data['table']['entity type'])) {
+      $entity_types[] = $base_table_data['table']['entity type'];
+    }
+
+    // Include all relationships.
+    foreach ($this->relationship as $relationship) {
+      $table_data = $views_data->get($relationship->definition['base']);
+      if (isset($table_data['table']['entity type'])) {
+        $entity_types[] = $table_data['table']['entity type'];
+      }
+    }
+
+    return array_values(array_unique($entity_types));
+  }
+
 }
