diff --git a/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php b/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php
index 07cf115..eda0725 100644
--- a/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php
+++ b/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php
@@ -7,11 +7,11 @@
 
 namespace Drupal\Core\Entity;
 
+use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Entity\Query\QueryInterface;
 use Drupal\Core\Language\Language;
 use Drupal\Component\Utility\NestedArray;
-use Drupal\Component\Uuid\Uuid;
 use Drupal\field\FieldInfo;
 use Drupal\field\FieldUpdateForbiddenException;
 use Drupal\field\FieldInterface;
@@ -83,6 +83,13 @@ class FieldableDatabaseStorageController extends FieldableEntityStorageControlle
   protected $fieldInfo;
 
   /**
+   * Cache backend.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface
+   */
+  protected $cacheBackend;
+
+  /**
    * The entity bundle key.
    *
    * @var string|bool
@@ -104,7 +111,8 @@ public static function createInstance(ContainerInterface $container, $entity_typ
       $entity_type,
       $entity_info,
       $container->get('database'),
-      $container->get('field.info')
+      $container->get('field.info'),
+      $container->get('cache.entity')
     );
   }
 
@@ -119,12 +127,15 @@ public static function createInstance(ContainerInterface $container, $entity_typ
    *   The database connection to be used.
    * @param \Drupal\field\FieldInfo $field_info
    *   The field info service.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
    */
-  public function __construct($entity_type, array $entity_info, Connection $database, FieldInfo $field_info) {
+  public function __construct($entity_type, array $entity_info, Connection $database, FieldInfo $field_info, CacheBackendInterface $cache) {
     parent::__construct($entity_type, $entity_info);
 
     $this->database = $database;
     $this->fieldInfo = $field_info;
+    $this->cacheBackend = $cache;
     $this->bundleKey = !empty($this->entityInfo['entity_keys']['bundle']) ? $this->entityInfo['entity_keys']['bundle'] : FALSE;
     $this->entityClass = $this->entityInfo['class'];
 
@@ -1467,4 +1478,102 @@ static public function _fieldColumnName(FieldInterface $field, $column) {
     return in_array($column, Field::getReservedColumns()) ? $column : $field->getFieldName() . '_' . $column;
   }
 
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function cacheGet($ids) {
+    $entities = parent::cacheGet($ids);
+    if ($this->cache) {
+      // Build the list of cache entries to retrieve.
+      $cids = array();
+      foreach ($ids as $id) {
+        if (!isset($entities[$id])) {
+          $cids[] = "entity:{$this->entityType}:$id";
+        }
+      }
+      if ($cids && $cache = $this->cacheBackend->getMultiple($cids)) {
+        // Put the cached field values back into the entities and remove them from
+        // the list of entities to query.
+        foreach ($ids as $id) {
+          $cid = "entity:{$this->entityType}:$id";
+          if (isset($cache[$cid])) {
+            $values = $cache[$cid]->data['values'];
+            $translations = $cache[$cid]->data['translations'];
+            $bundle = $this->bundleKey ? $cache[$cid]->data['bundle'] : FALSE;
+            $entities[$id] = new $this->entityClass($values, $this->entityType, $bundle, $translations);
+            // Already put the loaded entity into the cache.
+            $this->entityCache[$id] = $entities[$id];
+          }
+        }
+      }
+      return $entities;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function cacheSet($entities) {
+    if ($this->cache) {
+      foreach ($entities as $id => $entity) {
+        // Skip entities that are already in the static cache.
+        if (isset($this->entityCache[$id])) {
+          continue;
+        }
+
+        $data = array(
+          'id' => $entity->id(),
+          'bundle' => $entity->bundle(),
+          'translations' => array_keys($entity->getTranslationLanguages()),
+          'values' => array(),
+        );
+        foreach ($entity->getTranslationLanguages() as $langcode => $language) {
+          $translation = $entity->getTranslation($langcode);
+
+          // Make sure the default language is valid.
+          if ($entity->getUntranslated()->language()->id == $langcode) {
+            $langcode = Language::LANGCODE_DEFAULT;
+          }
+
+          foreach ($translation as $field_name => $items) {
+            if (!$items->isEmpty()) {
+              foreach ($items as $delta => $item) {
+                // If the field item needs to be prepare the cache data, call
+                // the corresponding method, otherwise use the values as cache
+                // data.
+                if ($item instanceof PrepareCacheInterface) {
+                  $data['values'][$field_name][$langcode][$delta] = $item->getCacheData();
+                }
+                else {
+                  $data['values'][$field_name][$langcode][$delta] = $item->getValue();
+                }
+              }
+            }
+          }
+        }
+        $cid = "entity:{$this->entityType}:$id";
+        $this->cacheBackend->set($cid, $data);
+      }
+    }
+    parent::cacheSet($entities);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function resetCache(array $ids = NULL) {
+    parent::resetCache($ids);
+    if ($ids) {
+      $cids = array();
+      foreach ($ids as $id) {
+        $cids[] = "entity:{$this->entityType}:$id";
+      }
+      $this->cacheBackend->deleteMultiple($cids);
+    }
+    else {
+      $this->cacheBackend->deleteAll();
+    }
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php b/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php
index f16d863..700cdcd 100644
--- a/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php
+++ b/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php
@@ -34,80 +34,12 @@
    *   indicated by each entity.
    */
   protected function loadFieldItems(array $entities, $age) {
-    if (empty($entities)) {
+    if (empty($entities) || empty($this->entityInfo['fieldable'])) {
       return;
     }
-
-    // Only the most current revision of non-deleted fields for cacheable entity
-    // types can be cached.
-    $load_current = $age == static::FIELD_LOAD_CURRENT;
-    $info = entity_get_info($this->entityType);
-    $use_cache = $load_current && $info['field_cache'];
-
-    // Assume all entities will need to be queried. Entities found in the cache
-    // will be removed from the list.
-    $queried_entities = $entities;
-
-    // Fetch available entities from cache, if applicable.
-    if ($use_cache) {
-      // Build the list of cache entries to retrieve.
-      $cids = array();
-      foreach ($entities as $id => $entity) {
-        $cids[] = "field:{$this->entityType}:$id";
-      }
-      $cache = cache('field')->getMultiple($cids);
-      // Put the cached field values back into the entities and remove them from
-      // the list of entities to query.
-      foreach ($entities as $id => $entity) {
-        $cid = "field:{$this->entityType}:$id";
-        if (isset($cache[$cid])) {
-          unset($queried_entities[$id]);
-          foreach ($cache[$cid]->data as $langcode => $values) {
-            $translation = $entity->getTranslation($langcode);
-            // We do not need to worry about field translatability here, the
-            // translation object will manage that automatically.
-            foreach ($values as $field_name => $items) {
-              $translation->$field_name = $items;
-            }
-          }
-        }
-      }
-    }
-
-    // Fetch other entities from their storage location.
-    if ($queried_entities) {
-      // Let the storage controller actually load the values.
-      $this->doLoadFieldItems($queried_entities, $age);
-
-      // Build cache data.
-      // @todo: Improve this logic to avoid instantiating field objects once
-      // the field logic is improved to not do that anyway.
-      if ($use_cache) {
-        foreach ($queried_entities as $id => $entity) {
-          $data = array();
-          foreach ($entity->getTranslationLanguages() as $langcode => $language) {
-            $translation = $entity->getTranslation($langcode);
-            foreach ($translation as $field_name => $items) {
-              if ($items instanceof ConfigFieldItemListInterface && !$items->isEmpty()) {
-                foreach ($items as $delta => $item) {
-                  // If the field item needs to prepare the cache data, call the
-                  // corresponding method, otherwise use the values as cache
-                  // data.
-                  if ($item instanceof PrepareCacheInterface) {
-                    $data[$langcode][$field_name][$delta] = $item->getCacheData();
-                  }
-                  else {
-                    $data[$langcode][$field_name][$delta] = $item->getValue();
-                  }
-                }
-              }
-            }
-          }
-          $cid = "field:{$this->entityType}:$id";
-          cache('field')->set($cid, $data);
-        }
-      }
-    }
+    // @todo: Drop these wrappers.
+    // Let the storage controller actually load the values.
+    $this->doLoadFieldItems($entities, $age);
   }
 
   /**
@@ -123,14 +55,8 @@ protected function loadFieldItems(array $entities, $age) {
    *   TRUE if the entity is being updated, FALSE if it is being inserted.
    */
   protected function saveFieldItems(EntityInterface $entity, $update = TRUE) {
+    // @todo: Drop these wrappers.
     $this->doSaveFieldItems($entity, $update);
-
-    if ($update) {
-      $entity_info = $entity->entityInfo();
-      if ($entity_info['field_cache']) {
-        cache('field')->delete('field:' . $entity->entityType() . ':' . $entity->id());
-      }
-    }
   }
 
   /**
@@ -144,12 +70,8 @@ protected function saveFieldItems(EntityInterface $entity, $update = TRUE) {
    *   The entity.
    */
   protected function deleteFieldItems(EntityInterface $entity) {
+    // @todo: Drop these wrappers.
     $this->doDeleteFieldItems($entity);
-
-    $entity_info = $entity->entityInfo();
-    if ($entity_info['field_cache']) {
-      cache('field')->delete('field:' . $entity->entityType() . ':' . $entity->id());
-    }
   }
 
   /**
diff --git a/core/modules/user/lib/Drupal/user/UserStorageController.php b/core/modules/user/lib/Drupal/user/UserStorageController.php
index 48e8206..bb433b0 100644
--- a/core/modules/user/lib/Drupal/user/UserStorageController.php
+++ b/core/modules/user/lib/Drupal/user/UserStorageController.php
@@ -8,6 +8,7 @@
 namespace Drupal\user;
 
 use Drupal\Component\Uuid\UuidInterface;
+use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Password\PasswordInterface;
 use Drupal\Core\Database\Connection;
@@ -49,15 +50,15 @@ class UserStorageController extends FieldableDatabaseStorageController implement
    *   The database connection to be used.
    * @param \Drupal\field\FieldInfo $field_info
    *   The field info service.
-   * @param \Drupal\Component\Uuid\UuidInterface $uuid_service
-   *   The UUID Service.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use..
    * @param \Drupal\Core\Password\PasswordInterface $password
    *   The password hashing service.
    * @param \Drupal\user\UserDataInterface $user_data
    *   The user data service.
    */
-  public function __construct($entity_type, $entity_info, Connection $database, FieldInfo $field_info, UuidInterface $uuid_service, PasswordInterface $password, UserDataInterface $user_data) {
-    parent::__construct($entity_type, $entity_info, $database, $field_info, $uuid_service);
+  public function __construct($entity_type, $entity_info, Connection $database, FieldInfo $field_info, CacheBackendInterface $cache, PasswordInterface $password, UserDataInterface $user_data) {
+    parent::__construct($entity_type, $entity_info, $database, $field_info, $cache);
 
     $this->password = $password;
     $this->userData = $user_data;
@@ -72,7 +73,7 @@ public static function createInstance(ContainerInterface $container, $entity_typ
       $entity_info,
       $container->get('database'),
       $container->get('field.info'),
-      $container->get('uuid'),
+      $container->get('cache.entity'),
       $container->get('password'),
       $container->get('user.data')
     );
