diff --git a/core/lib/Drupal/Core/Entity/Field/Field.php b/core/lib/Drupal/Core/Entity/Field/Field.php
index 3a0734b089e91fdfb501acc3f5387dcfa1fc598d..6f8382a44599fc52f860fc246432cd65f7881d88 100644
--- a/core/lib/Drupal/Core/Entity/Field/Field.php
+++ b/core/lib/Drupal/Core/Entity/Field/Field.php
@@ -56,6 +56,13 @@ public function __construct(array $definition, $name = NULL, TypedDataInterface
     $this->list[0] = $this->createItem(0);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getEntity() {
+    return $this->getParent();
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/lib/Drupal/Core/Entity/Field/FieldInterface.php b/core/lib/Drupal/Core/Entity/Field/FieldInterface.php
index 80b0412ffc1a484b859fc6d3f0b99cc762db66da..4708418970f52fdc7807d40becc54c9e322c6893 100644
--- a/core/lib/Drupal/Core/Entity/Field/FieldInterface.php
+++ b/core/lib/Drupal/Core/Entity/Field/FieldInterface.php
@@ -27,6 +27,14 @@
  */
 interface FieldInterface extends ListInterface, AccessibleInterface {
 
+  /**
+   * Gets the entity that field belongs to.
+   *
+   * @return \Drupal\Core\Entity\EntityInterface
+   *   The entity object.
+   */
+  public function getEntity();
+
   /**
    * Sets the langcode of the field values held in the object.
    *
diff --git a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php
index 0ac0a5d489c9e5e380c0775455cb5afe53809867..15744c0d5e5bf975db8197608e4ce87b7f268b71 100644
--- a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php
+++ b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php
@@ -36,6 +36,13 @@ public function __construct(array $definition, $name = NULL, TypedDataInterface
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getEntity() {
+    return $this->getParent()->getEntity();
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php b/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php
index e1f5d51b1e4b54d5f1884dd5b5628fa80a8303fe..71fc08646a7e612be0ab4621b48f7b265c0ce895 100644
--- a/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php
+++ b/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php
@@ -23,6 +23,14 @@
  */
 interface FieldItemInterface extends ComplexDataInterface {
 
+  /**
+   * Gets the entity that field belongs to.
+   *
+   * @return \Drupal\Core\Entity\EntityInterface
+   *   The entity object.
+   */
+  public function getEntity();
+
   /**
    * Gets the langcode of the field values held in the object.
    *
diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
index ca3d99ffd90d4201e553f37129cb4f646b8147cb..79ce7c917fcb43027ab2faa408f5f8a4023df675 100644
--- a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
+++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
@@ -21,9 +21,7 @@ class EntityChangedConstraintValidator extends ConstraintValidator {
    */
   public function validate($value, Constraint $constraint) {
     if (isset($value)) {
-      // We are on the field item level, so we need to go two levels up for the
-      // entity object.
-      $entity = $this->context->getMetadata()->getTypedData()->getParent()->getParent();
+      $entity = $this->context->getMetadata()->getTypedData()->getEntity();
       if (!$entity->isNew()) {
         $saved_entity = \Drupal::entityManager()->getStorageController($entity->entityType())->loadUnchanged($entity->id());
 
diff --git a/core/modules/comment/lib/Drupal/comment/CommentNewValue.php b/core/modules/comment/lib/Drupal/comment/CommentNewValue.php
index 1295776e91b58d104d42bf431549146e1145c5c8..4398a1beee95e195dd3f5c94410b395465740b36 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentNewValue.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentNewValue.php
@@ -26,8 +26,7 @@ public function getValue() {
       if (!isset($this->parent)) {
         throw new InvalidArgumentException('Computed properties require context for computation.');
       }
-      $field = $this->parent->getParent();
-      $entity = $field->getParent();
+      $entity = $this->parent->getEntity();
       $this->value = node_mark($entity->nid->target_id, $entity->changed->value);
     }
     return $this->value;
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php
index 443e509d918d44f49ed636b83fcc654c88e8a78b..6b3c1379e71fce444fdf9b004d46467ef6113653 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php
@@ -147,8 +147,7 @@ public function getSettableOptions() {
     if (function_exists($callback)) {
       // We are at the field item level, so we need to go two levels up to get
       // to the entity object.
-      $entity = $this->getParent()->getParent();
-      return $callback($this->getFieldDefinition(), $entity);
+      return $callback($this->getFieldDefinition(), $this->getEntity());
     }
   }
 
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php
index eb2e4dbbf792100e9aacb8c6ee25edb075824cb7..2eb001334603c0eed29efe7b51d2f9bb5f7f90bc 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php
@@ -37,8 +37,9 @@ public function __construct(array $definition, $name = NULL, TypedDataInterface
    * {@inheritdoc}
    */
   public function getFieldDefinition() {
-    if (!isset($this->instance) && $parent = $this->getParent()) {
-      $instances = FieldAPI::fieldInfo()->getBundleInstances($parent->entityType(), $parent->bundle());
+    if (!isset($this->instance)) {
+      $entity = $this->getEntity();
+      $instances = FieldAPI::fieldInfo()->getBundleInstances($entity->entityType(), $entity->bundle());
       $this->instance = $instances[$this->getName()];
     }
     return $this->instance;
@@ -69,7 +70,7 @@ public function getConstraints() {
    * {@inheritdoc}
    */
   protected function getDefaultValue() {
-    return $this->getFieldDefinition()->getFieldDefaultValue($this->getParent());
+    return $this->getFieldDefinition()->getFieldDefaultValue($this->getEntity());
   }
 
   /**
@@ -77,12 +78,11 @@ protected function getDefaultValue() {
    */
   public function defaultValuesForm(array &$form, array &$form_state) {
     if (empty($this->getFieldDefinition()->default_value_function)) {
-      $entity = $this->getParent();
       $widget = $this->defaultValueWidget($form_state);
 
       // Place the input in a separate place in the submitted values tree.
       $element = array('#parents' => array('default_value_input'));
-      $element += $widget->form($entity, $entity->language()->id, $this, $element, $form_state);
+      $element += $widget->form($this->getEntity(), $this->getLangcode(), $this, $element, $form_state);
 
       return $element;
     }
@@ -92,11 +92,11 @@ public function defaultValuesForm(array &$form, array &$form_state) {
    * {@inheritdoc}
    */
   public function defaultValuesFormValidate(array $element, array &$form, array &$form_state) {
-    $entity = $this->getParent();
-    $langcode = $entity->language()->id;
-    $widget = $this->defaultValueWidget($form_state);
+    $entity = $this->getEntity();
+    $langcode = $this->getLangcode();
 
     // Extract the submitted value, and validate it.
+    $widget = $this->defaultValueWidget($form_state);
     $widget->extractFormValues($entity, $langcode, $this, $element, $form_state);
     $violations = $this->validate();
 
@@ -116,12 +116,9 @@ public function defaultValuesFormValidate(array $element, array &$form, array &$
    * {@inheritdoc}
    */
   public function defaultValuesFormSubmit(array $element, array &$form, array &$form_state) {
-    $entity = $this->getParent();
-    $langcode = $entity->language()->id;
-    $widget = $this->defaultValueWidget($form_state);
-
     // Extract the submitted value, and return it as an array.
-    $widget->extractFormValues($entity, $langcode, $this, $element, $form_state);
+    $widget = $this->defaultValueWidget($form_state);
+    $widget->extractFormValues($this->getEntity(), $this->getLangcode(), $this, $element, $form_state);
     return $this->getValue();
   }
 
@@ -136,7 +133,7 @@ public function defaultValuesFormSubmit(array $element, array &$form, array &$fo
    */
   protected function defaultValueWidget(array &$form_state) {
     if (!isset($form_state['default_value_widget'])) {
-      $entity = $this->getParent();
+      $entity = $this->getEntity();
 
       // Force a non-required widget.
       $this->getFieldDefinition()->required = FALSE;
diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigField.php b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigField.php
index ce171badf369552cd95d506637bfdecba60d14d8..f99b0c61204c18150d11dda589ac4f315e0512a2 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigField.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigField.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\field\Plugin\field\field_type;
 
-use Drupal\Core\Entity\EntityInterface;
 use Drupal\field\Plugin\Type\FieldType\ConfigField;
 use Drupal\field\FieldInstanceInterface;
 use Symfony\Component\Validator\ConstraintViolation;
@@ -40,8 +39,7 @@ public function validate() {
     $legacy_errors = array();
     $this->legacyCallback('validate', array(&$legacy_errors));
 
-    $entity = $this->getParent();
-    $langcode = $entity->language()->id;
+    $langcode = $this->getLangcode();
     $field_name = $this->getFieldDefinition()->getFieldName();
 
     if (isset($legacy_errors[$field_name][$langcode])) {
@@ -108,19 +106,16 @@ protected function legacyCallback($hook, $args = array()) {
     $module = $definition['provider'];
     $callback = "{$module}_field_{$hook}";
     if (function_exists($callback)) {
-      $entity = $this->getParent();
-      $langcode = $entity->language()->id;
-
       // We need to remove the empty "prototype" item here.
       // @todo Revisit after http://drupal.org/node/1988492.
       $this->filterEmptyValues();
-      // Legcacy callbacks alter $items by reference.
+      // Legacy callbacks alter $items by reference.
       $items = (array) $this->getValue(TRUE);
       $args = array_merge(array(
-        $entity,
+        $this->getEntity(),
         $this->getFieldInstance()->getField(),
         $this->getFieldInstance(),
-        $langcode,
+        $this->getLangcode(),
         &$items
       ), $args);
       call_user_func_array($callback, $args);
diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
index 10fa23d36978ec2d507127218925f5f26251037b..e46622fb7422622b1d4e2c195b0182f12d954fed 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
@@ -88,8 +88,7 @@ public function instanceSettingsForm(array $form, array &$form_state) {
    */
   public function prepareCache() {
     if ($callback = $this->getLegacyCallback('load')) {
-      $entity = $this->getParent()->getParent();
-      $langcode = $entity->language()->id;
+      $entity = $this->getEntity();
       $entity_id = $entity->id();
 
       // hook_field_load() receives items keyed by entity id, and alters then by
@@ -100,7 +99,7 @@ public function prepareCache() {
         array($entity_id => $entity),
         $this->getFieldInstance()->getField(),
         array($entity_id => $this->getFieldInstance()),
-        $langcode,
+        $this->getLangcode(),
         &$items,
         EntityStorageControllerInterface::FIELD_LOAD_CURRENT,
       );
@@ -120,8 +119,7 @@ public function getSettableOptions() {
     $definition = $this->getPluginDefinition();
     $callback = "{$definition['provider']}_options_list";
     if (function_exists($callback)) {
-      $entity = $this->getParent()->getParent();
-      return $callback($this->getFieldDefinition(), $entity);
+      return $callback($this->getFieldDefinition(), $this->getEntity());
     }
   }
 
diff --git a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php
index 71436543cf7fef5e80c883088d9634b64194b9ad..a4f54f0d85d2f8c5e2787a30e68f2106e606e888 100644
--- a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php
+++ b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php
@@ -47,7 +47,7 @@ public function normalize($field_item, $format = NULL, array $context = array())
     // entity so that the items are properly added to the _links and _embedded
     // objects.
     $field_name = $field_item->getParent()->getName();
-    $entity = $field_item->getRoot();
+    $entity = $field_item->getEntity();
     $field_uri = $this->linkManager->getRelationUri($entity->entityType(), $entity->bundle(), $field_name);
     return array(
       '_links' => array(
diff --git a/core/modules/hal/lib/Drupal/hal/Normalizer/FieldNormalizer.php b/core/modules/hal/lib/Drupal/hal/Normalizer/FieldNormalizer.php
index 725fca35b097757b328ed4fcec5e56d642887b36..71d6672976953e23541bdc1abfb66a9a0037ee33 100644
--- a/core/modules/hal/lib/Drupal/hal/Normalizer/FieldNormalizer.php
+++ b/core/modules/hal/lib/Drupal/hal/Normalizer/FieldNormalizer.php
@@ -31,7 +31,7 @@ public function normalize($field, $format = NULL, array $context = array()) {
     $normalized_field_items = array();
 
     // Get the field definition.
-    $entity = $field->getParent();
+    $entity = $field->getEntity();
     $field_name = $field->getName();
     $field_definition = $entity->getPropertyDefinition($field_name);
 
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php
index f218438b86947c5bd33a6112e5814d2d1ded27c5..5081195f568b5ceaedf83b2db453c856c45f1c61 100644
--- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php
+++ b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php
@@ -143,7 +143,7 @@ protected function getOptions(FieldItemInterface $item) {
       $module_handler = \Drupal::moduleHandler();
       $context = array(
         'fieldDefinition' => $this->fieldDefinition,
-        'entity' => $item->getParent()->getParent(),
+        'entity' => $item->getEntity(),
       );
       $module_handler->alter('options_list', $options, $context);
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
index 12de782c73555903d91f53623736b5b891ed6337..ebc328dacd89e471a10e53119bbf8218a38d9280 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
@@ -391,12 +391,14 @@ protected function checkIntrospection($entity_type) {
 
     $field = $entity->user_id;
     $this->assertIdentical($field->getRoot(), $entity, 'Entity is root object.');
+    $this->assertIdentical($field->getEntity(), $entity, 'getEntity() returns the entity.');
     $this->assertEqual($field->getPropertyPath(), 'user_id');
     $this->assertEqual($field->getName(), 'user_id');
     $this->assertIdentical($field->getParent(), $entity, 'Parent object matches.');
 
     $field_item = $field[0];
     $this->assertIdentical($field_item->getRoot(), $entity, 'Entity is root object.');
+    $this->assertIdentical($field_item->getEntity(), $entity, 'getEntity() returns the entity.');
     $this->assertEqual($field_item->getPropertyPath(), 'user_id.0');
     $this->assertEqual($field_item->getName(), '0');
     $this->assertIdentical($field_item->getParent(), $field, 'Parent object matches.');
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
index e651e8bdce1c4b0667a9ea00f7c16e5078ae7cd7..21a3a2c76a1cddcd15d7fe904ff749945c41305a 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
@@ -75,7 +75,7 @@ public function formElement(FieldInterface $items, $delta, array $element, $lang
       '#default_value' => taxonomy_implode_tags($tags),
       '#autocomplete_route_name' => $this->getSetting('autocomplete_route_name'),
       '#autocomplete_route_parameters' => array(
-        'entity_type' => $items->getParent()->entityType(),
+        'entity_type' => $items->getEntity()->entityType(),
         'field_name' => $this->fieldDefinition->getFieldName(),
       ),
       '#size' => $this->getSetting('size'),