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 fa0b4a0..3354a72 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
@@ -205,6 +205,10 @@ public function getValue() {
     if ($this->hasNewEntity()) {
       $values['entity'] = $this->entity;
     }
+    // The NEW_ENTITY_MARKER is an implementation detail, don't return that.
+    if (isset($values['target_id']) && $this->getTargetId() === static::$NEW_ENTITY_MARKER) {
+      unset($values['target_id']);
+    }
     return $values;
   }
 
@@ -218,8 +222,8 @@ public function onChange($property_name, $notify = TRUE) {
       $target_id = $property->isTargetNew() ? static::$NEW_ENTITY_MARKER : $property->getTargetIdentifier();
       $this->writePropertyValue('target_id', $target_id);
     }
-    elseif ($property_name == 'target_id' && $this->target_id != static::$NEW_ENTITY_MARKER) {
-      $this->writePropertyValue('entity', $this->target_id);
+    elseif ($property_name == 'target_id' && $this->getTargetId() != static::$NEW_ENTITY_MARKER) {
+      $this->writePropertyValue('entity', $this->getTargetId());
     }
     parent::onChange($property_name, $notify);
   }
@@ -229,7 +233,7 @@ public function onChange($property_name, $notify = TRUE) {
    */
   public function isEmpty() {
     // Avoid loading the entity by first checking the 'target_id'.
-    if ($this->target_id !== NULL) {
+    if ($this->getTargetId() !== NULL) {
       return FALSE;
     }
     if ($this->entity && $this->entity instanceof EntityInterface) {
@@ -276,7 +280,7 @@ public static function generateSampleValue(FieldDefinitionInterface $field_defin
    *   TRUE if the item holds an unsaved entity.
    */
   public function hasNewEntity() {
-    return $this->target_id === static::$NEW_ENTITY_MARKER;
+    return $this->getTargetId() === static::$NEW_ENTITY_MARKER;
   }
 
   /**
@@ -303,6 +307,40 @@ public static function calculateDependencies(FieldDefinitionInterface $field_def
   /**
    * {@inheritdoc}
    */
+  public function __get($name) {
+    $value = parent::__get($name);
+    // The NEW_ENTITY_MARKER is an implementation detail, don't return that.
+    if ($name == 'target_id' && $value == static::$NEW_ENTITY_MARKER) {
+      return NULL;
+    }
+    return $value;
+  }
+
+  /**
+   * Returns the target id, even if the value is static::$NEW_ENTITY_MARKER.
+   *
+   * The entity reference item field-type internally uses
+   * static::$NEW_ENTITY_MARKER (-1) to track a reference to an unsaved entity.
+   * However if this value is emitted externally via serialization attempts to
+   * unserialize the field-type will result in an exception as the value cannot
+   * be used to set the target_id property.
+   *
+   * Accessing the target_id property via the __get method ($this->target_id)
+   * will return NULL if the value is static::$NEW_ENTITY_MARKER to ensure
+   * callers outside this object don't receive the internal implementation
+   * detail. However when accessing the property internally, there are valid
+   * cases where static::$NEW_ENTITY_MARKER should be returned. In such cases
+   * this method should be used as it bypasses self::__get and calls the parent
+   * method, which will return the value even if it is self::$NEW_ENTITY_MARKER.
+   */
+  protected function getTargetId() {
+    // Bypass self::__get which does not return static::$NEW_ENTITY_MARKER.
+    return parent::__get('target_id');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public static function onDependencyRemoval(FieldDefinitionInterface $field_definition, array $dependencies) {
     $changed = FALSE;
     if (!empty($field_definition->default_value)) {
diff --git a/core/modules/field/src/Tests/EntityReference/EntityReferenceItemTest.php b/core/modules/field/src/Tests/EntityReference/EntityReferenceItemTest.php
index 4601c34..ca724d5 100644
--- a/core/modules/field/src/Tests/EntityReference/EntityReferenceItemTest.php
+++ b/core/modules/field/src/Tests/EntityReference/EntityReferenceItemTest.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Field\FieldItemInterface;
 use Drupal\Core\Language\LanguageInterface;
+use Drupal\entity_test\Entity\EntityTest;
 use Drupal\entity_reference\Tests\EntityReferenceTestTrait;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\entity_test\Entity\EntityTestStringId;
@@ -228,6 +229,30 @@ public function testConfigEntityReferenceItem() {
   }
 
   /**
+   * Tests entity auto create.
+   */
+  public function testEntityAutoCreate() {
+    // The term entity is unsaved here.
+    $term = Term::create(array(
+      'name' => $this->randomMachineName(),
+      'vid' => $this->term->bundle(),
+      'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
+    ));
+    $entity = EntityTest::create();
+    // Now assign the unsaved term to the field.
+    $entity->field_test_taxonomy_term->entity = $term;
+    $entity->name->value = $this->randomMachineName();
+    // This is equal to storing an entity to tempstore or cache and retrieving
+    // it back. An example for this is node preview.
+    $entity = serialize($entity);
+    $entity = unserialize($entity);
+    // And then the entity.
+    $entity->save();
+    $term = \Drupal::entityManager()->loadEntityByUuid($term->getEntityTypeId(), $term->uuid());
+    $this->assertEqual($entity->field_test_taxonomy_term->entity->id(), $term->id());
+  }
+
+  /**
    * Test saving order sequence doesn't matter.
    */
   public function testEntitySaveOrder() {
@@ -243,6 +268,12 @@ public function testEntitySaveOrder() {
     $entity->name->value = $this->randomMachineName();
     // Now save the term.
     $term->save();
+    // Now get the field value.
+    $value = $entity->get('field_test_taxonomy_term');
+    $this->assertTrue(empty($value['target_id']));
+    $this->assertNull($entity->field_test_taxonomy_term->target_id);
+    // And then set it.
+    $entity->field_test_taxonomy_term = $value;
     // And then the entity.
     $entity->save();
     $this->assertEqual($entity->field_test_taxonomy_term->entity->id(), $term->id());
