diff --git a/core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php
new file mode 100644
index 0000000..c7b80c4
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\EntityReferenceFieldItemList.
+ */
+
+namespace Drupal\Core\Field;
+
+/**
+ * Defines a item list class for entity reference fields.
+ */
+class EntityReferenceFieldItemList extends FieldItemList implements EntityReferenceFieldItemListInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function referencedEntities() {
+    // Get a list of items having non-empty target ids.
+    $list = array_filter($this->list, function($item) {
+      return (bool) $item->target_id;
+    });
+
+    $ids = array();
+    foreach ($list as $delta => $item) {
+      $ids[$delta] = $item->target_id;
+    }
+    if (empty($ids)) {
+      return array();
+    }
+
+    $target_type = $this->getFieldDefinition()->getFieldSetting('target_type');
+    $entities = \Drupal::entityManager()->getStorageController($target_type)->loadMultiple($ids);
+
+    $target_entities = array();
+    foreach ($ids as $delta => $target_id) {
+      if (isset($entities[$target_id])) {
+        $target_entities[$delta] = $entities[$target_id];
+      }
+    }
+
+    return $target_entities;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Field/EntityReferenceFieldItemListInterface.php b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemListInterface.php
new file mode 100644
index 0000000..5c6985e
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemListInterface.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\EntityReferenceFieldItemListInterface.
+ */
+
+namespace Drupal\Core\Field;
+
+/**
+ * Interface for entity reference lists of field items.
+ */
+interface EntityReferenceFieldItemListInterface extends FieldItemListInterface {
+
+  /**
+   * Returns all the entities referenced by this field, preserving field item
+   * deltas.
+   *
+   * @return \Drupal\Core\Entity\EntityInterface[]
+   *   An array of entity objects keyed by field item deltas.
+   */
+  public function referencedEntities();
+
+}
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ConfigurableEntityReferenceFieldItemList.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ConfigurableEntityReferenceFieldItemList.php
new file mode 100644
index 0000000..3af05f3
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ConfigurableEntityReferenceFieldItemList.php
@@ -0,0 +1,131 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\Plugin\Field\FieldType\ConfigurableEntityReferenceFieldItemList.
+ */
+
+namespace Drupal\Core\Field\Plugin\Field\FieldType;
+
+use Drupal\Core\Field\ConfigFieldItemList;
+use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
+
+/**
+ * Represents a configurable entity_reference entity field.
+ */
+class ConfigurableEntityReferenceFieldItemList extends ConfigFieldItemList implements EntityReferenceFieldItemListInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getDefaultValue() {
+    $default_value = parent::getDefaultValue();
+
+    if ($default_value) {
+      // Convert UUIDs to numeric IDs.
+      $uuids = array();
+      $fixed = array();
+      foreach ($default_value as $delta => $properties) {
+        if ($properties['target_uuid'] == 'anonymous' || $properties['target_uuid'] == 'administrator') {
+          $fixed[$delta] = ($properties['target_uuid'] == 'anonymous') ? '0' : '1';
+        }
+        else {
+          $uuids[$delta] = $properties['target_uuid'];
+        }
+      }
+      if ($uuids) {
+        $target_type = $this->getFieldDefinition()->getSetting('target_type');
+        $entity_ids = \Drupal::entityQuery($target_type)
+          ->condition('uuid', $uuids, 'IN')
+          ->execute();
+        $entities = \Drupal::entityManager()
+          ->getStorageController($target_type)
+          ->loadMultiple($entity_ids);
+
+        foreach ($entities as $id => $entity) {
+          $entity_ids[$entity->uuid()] = $id;
+        }
+        foreach ($uuids as $delta => $uuid) {
+          if ($entity_ids[$uuid]) {
+            $default_value[$delta]['target_id'] = $entity_ids[$uuid];
+            unset($default_value[$delta]['target_uuid']);
+          }
+          else {
+            unset($default_value[$delta]);
+          }
+        }
+      }
+
+      if ($fixed) {
+        foreach ($fixed as $delta => $id) {
+          $default_value[$delta]['target_id'] = $id;
+          unset($default_value[$delta]['target_uuid']);
+        }
+      }
+
+      // Ensure we return consecutive deltas, in case we removed unknown UUIDs.
+      $default_value = array_values($default_value);
+    }
+    return $default_value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultValuesFormSubmit(array $element, array &$form, array &$form_state) {
+    $default_value = parent::defaultValuesFormSubmit($element, $form, $form_state);
+
+    // Convert numeric IDs to UUIDs to ensure config deployability.
+    $ids = array();
+    foreach ($default_value as $delta => $properties) {
+      $ids[] = $properties['target_id'];
+    }
+    $entities = \Drupal::entityManager()
+      ->getStorageController($this->getFieldDefinition()->getSetting('target_type'))
+      ->loadMultiple($ids);
+
+    foreach ($default_value as $delta => $properties) {
+      $uuid = $entities[$properties['target_id']]->uuid();
+      // @todo Some entities do not have uuid. IE: Anonymous and admin user.
+      //   Remove this special case once http://drupal.org/node/2050843
+      //   has been fixed.
+      if (!$uuid) {
+        $uuid = ($properties['target_id'] == '0') ? 'anonymous' : 'administrator';
+      }
+      unset($default_value[$delta]['target_id']);
+      $default_value[$delta]['target_uuid'] = $uuid;
+    }
+    return $default_value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function referencedEntities() {
+    // Get a list of items having non-empty target ids.
+    $list = array_filter($this->list, function($item) {
+      return (bool) $item->target_id;
+    });
+
+    $ids = array();
+    foreach ($list as $delta => $item) {
+      $ids[$delta] = $item->target_id;
+    }
+    if (empty($ids)) {
+      return array();
+    }
+
+    $target_type = $this->getFieldDefinition()->getSetting('target_type');
+    $entities = \Drupal::entityManager()->getStorageController($target_type)->loadMultiple($ids);
+
+    $target_entities = array();
+    foreach ($ids as $delta => $target_id) {
+      if (isset($entities[$target_id])) {
+        $target_entities[$delta] = $entities[$target_id];
+      }
+    }
+
+    return $target_entities;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
index 655f4fd..4276f21 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
@@ -24,6 +24,7 @@
  *   label = @Translation("Entity reference"),
  *   description = @Translation("An entity field containing an entity reference."),
  *   configurable = FALSE,
+ *   list_class = "\Drupal\Core\Field\EntityReferenceFieldItemList",
  *   constraints = {"ValidReference" = TRUE}
  * )
  */
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index e44cc32..7231cc3 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -24,7 +24,7 @@ function entity_reference_field_info_alter(&$info) {
   $info['entity_reference']['instance_settings']['handler_settings'] = array();
   $info['entity_reference']['default_widget'] = 'entity_reference_autocomplete';
   $info['entity_reference']['default_formatter'] = 'entity_reference_label';
-  $info['entity_reference']['list_class'] = '\Drupal\entity_reference\Plugin\Field\FieldType\ConfigurableEntityReferenceFieldItemList';
+  $info['entity_reference']['list_class'] = '\Drupal\Core\Field\Plugin\Field\FieldType\ConfigurableEntityReferenceFieldItemList';
   $info['entity_reference']['provider'] = 'entity_reference';
 }
 
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldType/ConfigurableEntityReferenceFieldItemList.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldType/ConfigurableEntityReferenceFieldItemList.php
deleted file mode 100644
index 9623c43..0000000
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldType/ConfigurableEntityReferenceFieldItemList.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\entity_reference\Plugin\Field\FieldType\ConfigurableEntityReferenceFieldItemList.
- */
-
-namespace Drupal\entity_reference\Plugin\Field\FieldType;
-
-use Drupal\Core\Field\ConfigFieldItemList;
-
-/**
- * Represents a configurable entity_reference entity field.
- */
-class ConfigurableEntityReferenceFieldItemList extends ConfigFieldItemList {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getDefaultValue() {
-    $default_value = parent::getDefaultValue();
-
-    if ($default_value) {
-      // Convert UUIDs to numeric IDs.
-      $uuids = array();
-      $fixed = array();
-      foreach ($default_value as $delta => $properties) {
-        if ($properties['target_uuid'] == 'anonymous' || $properties['target_uuid'] == 'administrator') {
-          $fixed[$delta] = ($properties['target_uuid'] == 'anonymous') ? '0' : '1';
-        }
-        else {
-          $uuids[$delta] = $properties['target_uuid'];
-        }
-      }
-      if ($uuids) {
-        $target_type = $this->getFieldDefinition()->getSetting('target_type');
-        $entity_ids = \Drupal::entityQuery($target_type)
-          ->condition('uuid', $uuids, 'IN')
-          ->execute();
-        $entities = \Drupal::entityManager()
-          ->getStorageController($target_type)
-          ->loadMultiple($entity_ids);
-
-        foreach ($entities as $id => $entity) {
-          $entity_ids[$entity->uuid()] = $id;
-        }
-        foreach ($uuids as $delta => $uuid) {
-          if ($entity_ids[$uuid]) {
-            $default_value[$delta]['target_id'] = $entity_ids[$uuid];
-            unset($default_value[$delta]['target_uuid']);
-          }
-          else {
-            unset($default_value[$delta]);
-          }
-        }
-      }
-
-      if ($fixed) {
-        foreach ($fixed as $delta => $id) {
-          $default_value[$delta]['target_id'] = $id;
-          unset($default_value[$delta]['target_uuid']);
-        }
-      }
-
-      // Ensure we return consecutive deltas, in case we removed unknown UUIDs.
-      $default_value = array_values($default_value);
-    }
-    return $default_value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function defaultValuesFormSubmit(array $element, array &$form, array &$form_state) {
-    $default_value = parent::defaultValuesFormSubmit($element, $form, $form_state);
-
-    // Convert numeric IDs to UUIDs to ensure config deployability.
-    $ids = array();
-    foreach ($default_value as $delta => $properties) {
-      $ids[] = $properties['target_id'];
-    }
-    $entities = \Drupal::entityManager()
-      ->getStorageController($this->getFieldDefinition()->getSetting('target_type'))
-      ->loadMultiple($ids);
-
-    foreach ($default_value as $delta => $properties) {
-      $uuid = $entities[$properties['target_id']]->uuid();
-      // @todo Some entities do not have uuid. IE: Anonymous and admin user.
-      //   Remove this special case once http://drupal.org/node/2050843
-      //   has been fixed.
-      if (!$uuid) {
-        $uuid = ($properties['target_id'] == '0') ? 'anonymous' : 'administrator';
-      }
-      unset($default_value[$delta]['target_id']);
-      $default_value[$delta]['target_uuid'] = $uuid;
-    }
-    return $default_value;
-  }
-
-}
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php
index 4119240..187dbe3 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php
@@ -9,6 +9,7 @@
 
 use Drupal\system\Tests\Entity\EntityUnitTestBase;
 use Drupal\field\Field;
+use Drupal\Core\Field\FieldDefinitionInterface;
 
 /**
  * Tests for the entity reference field.
@@ -117,4 +118,62 @@ public function testEntityReferenceFieldValidation() {
     // https://drupal.org/node/2064191 is fixed
   }
 
+  /**
+   * Tests the multiple target entities loader.
+   */
+  public function testReferencedEntitiesMultipleLoad() {
+    // Set unlimited cardinality for 'entity_test.field_test' field.
+    $field = entity_load('field_entity', $this->entityType . '.' . $this->fieldName);
+    $field->cardinality = FieldDefinitionInterface::CARDINALITY_UNLIMITED;
+    $field->save();
+
+    // Create the parent entity.
+    $entity = entity_create($this->entityType, array('type' => $this->bundle));
+
+    // Create three target entities and attach them to parent field.
+    $target_entities = array();
+    $reference_field = array();
+    for ($i = 0; $i < 3; $i++) {
+      $target_entity = entity_create($this->referencedEntityType, array('type' => $this->bundle));
+      $target_entity->save();
+      $target_entities[] = $target_entity;
+      $reference_field[]['target_id'] = $target_entity->id();
+    }
+
+    // Also attach a non-existent entity and a NULL target id.
+    $reference_field[3]['target_id'] = 99999;
+    $target_entities[3] = NULL;
+    $reference_field[4]['target_id'] = NULL;
+    $target_entities[4] = NULL;
+
+    // Attach the first created target entity as the sixth item ($delta == 5) of
+    // the parent entity field. We want to test the case when the same target
+    // entity is referenced twice (or more times) in the same entity reference
+    // field.
+    $reference_field[5] = $reference_field[0];
+    $target_entities[5] = $target_entities[0];
+
+    // Set the field value.
+    $entity->{$this->fieldName}->setValue($reference_field);
+
+    // Load the target entities using EntityReferenceField::referencedEntities().
+    $entities = $entity->{$this->fieldName}->referencedEntities();
+
+    // Test returned entities:
+    // - Deltas must be preserved.
+    // - Non-existent entities must not be retrieved in target entities result.
+    foreach ($target_entities as $delta => $target_entity) {
+      if (!empty($target_entity)) {
+        // There must be an entity in the loaded set having the same id for the
+        // same delta.
+        $this->assertEqual($target_entity->id(), $entities[$delta]->id());
+      }
+      else {
+        // A non-existent or NULL entity target id must not return any item in
+        // the target entities set.
+        $this->assertFalse(isset($loaded_entities[$delta]));
+      }
+    }
+  }
+
 }
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileFieldItemList.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileFieldItemList.php
index 2b750b0..60d02cc 100644
--- a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileFieldItemList.php
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileFieldItemList.php
@@ -7,12 +7,19 @@
 
 namespace Drupal\file\Plugin\Field\FieldType;
 
-use Drupal\Core\Field\ConfigFieldItemList;
+use Drupal\Core\Field\Plugin\Field\FieldType\ConfigurableEntityReferenceFieldItemList;
 
 /**
  * Represents a configurable entity file field.
  */
-class FileFieldItemList extends ConfigFieldItemList {
+class FileFieldItemList extends ConfigurableEntityReferenceFieldItemList {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefaultValue() {
+    return NULL;
+  }
 
   /**
    * {@inheritdoc}
@@ -22,12 +29,22 @@ public function defaultValuesForm(array &$form, array &$form_state) { }
   /**
    * {@inheritdoc}
    */
+  public function defaultValuesFormValidate(array $element, array &$form, array &$form_state) { }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultValuesFormSubmit(array $element, array &$form, array &$form_state) { }
+
+  /**
+   * {@inheritdoc}
+   */
   public function insert() {
     parent::insert();
     $entity = $this->getEntity();
 
     // Add a new usage for newly uploaded files.
-    foreach ($this->targetEntities() as $file) {
+    foreach ($this->referencedEntities() as $file) {
       \Drupal::service('file.usage')->add($file, 'file', $entity->entityType(), $entity->id());
     }
   }
@@ -40,8 +57,12 @@ public function update() {
     $entity = $this->getEntity();
 
     // Get current target file entities and file IDs.
-    $files = $this->targetEntities();
-    $fids = array_keys($files);
+    $files = $this->referencedEntities();
+    $fids = array();
+
+    foreach ($files as $file) {
+      $fids[] = $file->id();
+    }
 
     // On new revisions, all files are considered to be a new usage and no
     // deletion of previous file usages are necessary.
@@ -68,8 +89,8 @@ public function update() {
     }
 
     // Add new usage entries for newly added files.
-    foreach ($files as $fid => $file) {
-      if (!in_array($fid, $original_fids)) {
+    foreach ($files as $file) {
+      if (!in_array($file->id(), $original_fids)) {
         \Drupal::service('file.usage')->add($file, 'file', $entity->entityType(), $entity->id());
       }
     }
@@ -83,7 +104,7 @@ public function delete() {
     $entity = $this->getEntity();
 
     // Delete all file usages within this entity.
-    foreach ($this->targetEntities() as $file) {
+    foreach ($this->referencedEntities() as $file) {
       \Drupal::service('file.usage')->delete($file, 'file', $entity->entityType(), $entity->id(), 0);
     }
   }
@@ -96,31 +117,9 @@ public function deleteRevision() {
     $entity = $this->getEntity();
 
     // Decrement the file usage by 1.
-    foreach ($this->targetEntities() as $file) {
+    foreach ($this->referencedEntities() as $file) {
       \Drupal::service('file.usage')->delete($file, 'file', $entity->entityType(), $entity->id());
     }
   }
 
-  /**
-   * Collects target file entities for this field.
-   *
-   * @return array
-   *   An array with the list of target file entities keyed by file ID.
-   *
-   * @todo Drop this when https://drupal.org/node/2073661 lands.
-   */
-  protected function targetEntities() {
-    if (!isset($this->list)) {
-      return array();
-    }
-    $ids = array();
-    foreach ($this->list as $item) {
-      $ids[] = $item->target_id;
-    }
-    // Prevent NULLs as target IDs.
-    $ids = array_filter($ids);
-
-    return $ids ? \Drupal::entityManager()->getStorageController('file')->loadMultiple($ids) : array();
-  }
-
 }
diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
index 188ae85..6d7b908 100644
--- a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
+++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldType/FileItem.php
@@ -22,7 +22,8 @@
  *   settings = {
  *     "display_field" = "0",
  *     "display_default" = "0",
- *     "uri_scheme" = ""
+ *     "uri_scheme" = "",
+ *     "target_type" = "file"
  *   },
  *   instance_settings = {
  *     "file_extensions" = "txt",
diff --git a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
index 59e464c..7621604 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldType/ImageItem.php
@@ -40,7 +40,8 @@
  *         "label" = @Translation("Title"),
  *         "translatable" = TRUE
  *       }
- *     }
+ *     },
+ *     "target_type" = "file",
  *   },
  *   instance_settings = {
  *     "file_extensions" = "png gif jpg jpeg",
