diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index a15279e..24c5ed4 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -11,7 +11,6 @@
 use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterMatchersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterRouteFiltersPass;
-use Drupal\Core\DependencyInjection\Compiler\RegisterSerializationClassesPass;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\DependencyInjection\Reference;
@@ -249,20 +248,6 @@ public function build(ContainerBuilder $container) {
     $container
       ->register('transliteration', 'Drupal\Core\Transliteration\PHPTransliteration');
 
-    // Add Serializer with arguments to be replaced in the compiler pass.
-    $container->register('serializer', 'Symfony\Component\Serializer\Serializer')
-      ->addArgument(array())
-      ->addArgument(array());
-
-    $container->register('serializer.normalizer.complex_data', 'Drupal\Core\Serialization\ComplexDataNormalizer')->addTag('normalizer');
-    $container->register('serializer.normalizer.list', 'Drupal\Core\Serialization\ListNormalizer')->addTag('normalizer');
-    $container->register('serializer.normalizer.typed_data', 'Drupal\Core\Serialization\TypedDataNormalizer')->addTag('normalizer');
-
-    $container->register('serializer.encoder.json', 'Drupal\Core\Serialization\JsonEncoder')
-      ->addTag('encoder', array('format' => array('json' => 'JSON')));
-    $container->register('serializer.encoder.xml', 'Drupal\Core\Serialization\XmlEncoder')
-      ->addTag('encoder', array('format' => array('xml' => 'XML')));
-
     $container->register('flood', 'Drupal\Core\Flood\DatabaseBackend')
       ->addArgument(new Reference('database'));
 
@@ -270,8 +255,6 @@ public function build(ContainerBuilder $container) {
     $container->addCompilerPass(new RegisterRouteFiltersPass());
     // Add a compiler pass for registering event subscribers.
     $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
-    // Add a compiler pass for adding Normalizers and Encoders to Serializer.
-    $container->addCompilerPass(new RegisterSerializationClassesPass());
     // Add a compiler pass for registering event subscribers.
     $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
     $container->addCompilerPass(new RegisterAccessChecksPass());
diff --git a/core/lib/Drupal/Core/Serialization/NormalizerBase.php b/core/lib/Drupal/Core/Serialization/NormalizerBase.php
index f256b0e..5b370a6 100644
--- a/core/lib/Drupal/Core/Serialization/NormalizerBase.php
+++ b/core/lib/Drupal/Core/Serialization/NormalizerBase.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\Core\Serialization;
 
-use Drupal\Core\Entity\EntityInterface;
+use Drupal\serialization\Plugin\Type\EntityReferenceHandlerPluginManager;
 use Symfony\Component\Serializer\Exception\RuntimeException;
 use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 use Symfony\Component\Serializer\Normalizer\SerializerAwareNormalizer;
@@ -24,6 +24,8 @@
    */
   protected static $supportedInterfaceOrClass;
 
+  protected $entityReferenceHandlerPluginManager;
+
   /**
    * Implements \Symfony\Component\Serializer\Normalizer\NormalizerInterface::supportsNormalization().
    */
@@ -31,4 +33,8 @@ public function supportsNormalization($data, $format = NULL) {
     return is_object($data) && ($data instanceof static::$supportedInterfaceOrClass);
   }
 
+  public function setEntityReferenceHandlerPluginManager(EntityReferenceHandlerPluginManager $plugin_manager) {
+    $this->entityReferenceHandlerPluginManager = $plugin_manager;
+  }
+
 }
diff --git a/core/modules/jsonld/jsonld.info b/core/modules/jsonld/jsonld.info
index fce4688..6e89779 100644
--- a/core/modules/jsonld/jsonld.info
+++ b/core/modules/jsonld/jsonld.info
@@ -4,3 +4,4 @@ package = Core
 version = VERSION
 core = 8.x
 dependencies[] = rdf
+dependencies[] = serialization
diff --git a/core/modules/jsonld/lib/Drupal/jsonld/JsonldBundle.php b/core/modules/jsonld/lib/Drupal/jsonld/JsonldBundle.php
index 3024883..b62328f 100644
--- a/core/modules/jsonld/lib/Drupal/jsonld/JsonldBundle.php
+++ b/core/modules/jsonld/lib/Drupal/jsonld/JsonldBundle.php
@@ -51,6 +51,7 @@ public function build(ContainerBuilder $container) {
         $container->register("serializer.normalizer.{$supported_class}.{$format}", $normalizer_class)
           ->addArgument(new Reference('rdf.site_schema_manager'))
           ->addArgument(new Reference('rdf.mapping_manager'))
+          ->addMethodCall('setEntityReferenceHandlerPluginManager', array(new Reference('plugin.manager.serialization.entityreference_handler')))
           ->addTag('normalizer', array('priority' => $priority));
       }
     }
diff --git a/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityNormalizer.php b/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityNormalizer.php
index ab662b3..1e15adf 100644
--- a/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityNormalizer.php
+++ b/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityNormalizer.php
@@ -8,6 +8,7 @@
 namespace Drupal\jsonld;
 
 use Drupal\jsonld\JsonldNormalizerBase;
+use Drupal\serialization\Plugin\Type\EntityReferenceHandlerPluginManager;
 use Drupal\rdf\RdfMappingException;
 use Symfony\Component\Serializer\Exception\UnexpectedValueException;
 use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
@@ -88,6 +89,7 @@ public function denormalize($data, $class, $format = null, array $context = arra
       }
     }
 
+    $entityreference_settings = serialization_get_entityreference_handler_settings($entity->entityType(), $entity->bundle(), $format);
     // For each attribute in the JSON-LD, add the values as fields to the newly
     // created entity. It is assumed that the JSON attribute names are the same
     // as the site's field names.
@@ -112,7 +114,13 @@ public function denormalize($data, $class, $format = null, array $context = arra
       // The vnd.drupal.ld+json mime type will always use language keys, per
       // http://drupal.org/node/1838700.
       foreach ($incomingFieldValues as $langcode => $incomingFieldItems) {
-        $fieldValue = $this->serializer->denormalize($incomingFieldItems, $fieldItemClass, $format);
+        $context = array();
+        if ($handler_settings = $entityreference_settings->getHandler($fieldName)) {
+          $field_definition = $entity->getPropertyDefinition($fieldName);
+          $handler_settings['settings']['target_entity_type'] = $field_definition['settings']['entity type'];
+          $context['entityreference_handler'] = $this->entityReferenceHandlerPluginManager->createInstance($handler_settings['plugin_id'], $handler_settings['settings']);
+        }
+        $fieldValue = $this->serializer->denormalize($incomingFieldItems, $fieldItemClass, $format, $context);
         $entity->getTranslation($langcode)
           ->set($fieldName, $fieldValue);
       }
diff --git a/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityReferenceNormalizer.php b/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityReferenceNormalizer.php
index f57066d..c740c81 100644
--- a/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityReferenceNormalizer.php
+++ b/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityReferenceNormalizer.php
@@ -30,15 +30,17 @@ class JsonldEntityReferenceNormalizer extends JsonldNormalizerBase implements De
   /**
    * Implements \Symfony\Component\Serializer\Normalizer\NormalizerInterface::normalize()
    */
-  public function normalize($object, $format = NULL, array $context = array()) {
-    // @todo If an $options parameter is added to the serialize signature, as
+  public function normalize($object, $format = null, array $context = array()) {
+    // @todo Since the context parameter was added to Serilizer's interface, as
     // requested in https://github.com/symfony/symfony/pull/4938, then instead
     // of creating the array of properties, we could simply call normalize and
     // pass in the referenced entity with a flag that ensures it is rendered as
     // a node reference and not a node definition.
     $entity_wrapper = new JsonldEntityWrapper($object->entity, $format, $this->serializer, $this->siteSchemaManager);
+    $properties = $entity_wrapper->getProperties();
     return array(
       '@id' => $entity_wrapper->getId(),
+      'uuid' => $properties['uuid'],
     );
   }
 
@@ -46,8 +48,13 @@ public function normalize($object, $format = NULL, array $context = array()) {
    * Implements \Symfony\Component\Serializer\Normalizer\DenormalizerInterface::denormalize()
    */
   public function denormalize($data, $class, $format = null, array $context = array()) {
-    // @todo Support denormalization for Entity Reference.
-    return array();
+    $return = array();
+    $entityreference_handler = $context['entityreference_handler'];
+
+    foreach ($data as $node) {
+      $return[]['value'] = $entityreference_handler->getEntityId($node, $format, $this->serializer);
+    }
+    return $return;
   }
 
   /**
diff --git a/core/modules/jsonld/lib/Drupal/jsonld/JsonldNormalizerBase.php b/core/modules/jsonld/lib/Drupal/jsonld/JsonldNormalizerBase.php
index e898da8..74b2111 100644
--- a/core/modules/jsonld/lib/Drupal/jsonld/JsonldNormalizerBase.php
+++ b/core/modules/jsonld/lib/Drupal/jsonld/JsonldNormalizerBase.php
@@ -8,6 +8,7 @@
 namespace Drupal\jsonld;
 
 use ReflectionClass;
+use Drupal\Core\Serialization\NormalizerBase;
 use Drupal\rdf\RdfMappingManager;
 use Drupal\rdf\SiteSchema\SiteSchemaManager;
 use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
@@ -16,14 +17,7 @@
 /**
  * Provide a base class for JSON-LD Normalizers.
  */
-abstract class JsonldNormalizerBase extends SerializerAwareNormalizer implements NormalizerInterface {
-
-  /**
-   * The interface or class that this Normalizer supports.
-   *
-   * @var string
-   */
-  protected static $supportedInterfaceOrClass;
+abstract class JsonldNormalizerBase extends NormalizerBase {
 
   /**
    * The formats that this Normalizer supports.
@@ -60,7 +54,7 @@ public function __construct(SiteSchemaManager $site_schema_manager, RdfMappingMa
   }
 
   /**
-   * Implements \Symfony\Component\Serializer\Normalizer\NormalizerInterface::normalize()
+   * Overrides \Drupal\Core\Serialization\NormalizerBase::supportsNormalization()
    */
   public function supportsNormalization($data, $format = NULL) {
     return is_object($data) && in_array($format, static::$format) && ($data instanceof static::$supportedInterfaceOrClass);
diff --git a/core/modules/jsonld/lib/Drupal/jsonld/Tests/JsonldTestSetupHelper.php b/core/modules/jsonld/lib/Drupal/jsonld/Tests/JsonldTestSetupHelper.php
index d0eb0c3..5ddf281 100644
--- a/core/modules/jsonld/lib/Drupal/jsonld/Tests/JsonldTestSetupHelper.php
+++ b/core/modules/jsonld/lib/Drupal/jsonld/Tests/JsonldTestSetupHelper.php
@@ -15,6 +15,7 @@
 use Drupal\rdf\RdfMappingManager;
 use Drupal\rdf\EventSubscriber\MappingSubscriber;
 use Drupal\rdf\SiteSchema\SiteSchemaManager;
+use Drupal\serialization\Plugin\Type\EntityReferenceHandlerPluginManager;
 use Symfony\Component\EventDispatcher\EventDispatcher;
 use Symfony\Component\Serializer\Serializer;
 
@@ -45,6 +46,13 @@ class JsonldTestSetupHelper {
   protected $normalizers;
 
   /**
+   * The Serializer.
+   *
+   * @var \Symfony\Component\Serializer\Serializer
+   */
+  protected $serializer;
+
+  /**
    * Constructor.
    */
   public function __construct() {
@@ -60,8 +68,10 @@ public function __construct() {
       'field_item' => new JsonldFieldItemNormalizer($this->siteSchemaManager, $this->rdfMappingManager),
       'entity' => new JsonldEntityNormalizer($this->siteSchemaManager, $this->rdfMappingManager),
     );
-    $serializer = new Serializer($this->normalizers, array(new JsonldEncoder()));
-    $this->normalizers['entity']->setSerializer($serializer);
+    $this->serializer = new Serializer($this->normalizers, array(new JsonldEncoder()));
+    $this->normalizers['entity']->setSerializer($this->serializer);
+    $this->normalizers['entity']->setEntityReferenceHandlerPluginManager(new EntityReferenceHandlerPluginManager());
+
   }
 
   /**
@@ -75,6 +85,16 @@ public function getNormalizers() {
   }
 
   /**
+   * Get Serializer.
+   *
+   * @return \Symfony\Component\Serializer\Serializer
+   *   The serializer.
+   */
+  public function getSerializer() {
+    return $this->serializer;
+  }
+
+  /**
    * Get the SiteSchemaManager object.
    *
    * @return \Drupal\rdf\SiteSchema\SiteSchemaManager
diff --git a/core/modules/jsonld/lib/Drupal/jsonld/Tests/NormalizeDenormalizeTest.php b/core/modules/jsonld/lib/Drupal/jsonld/Tests/NormalizeDenormalizeTest.php
index a9e057d..75edfac 100644
--- a/core/modules/jsonld/lib/Drupal/jsonld/Tests/NormalizeDenormalizeTest.php
+++ b/core/modules/jsonld/lib/Drupal/jsonld/Tests/NormalizeDenormalizeTest.php
@@ -145,6 +145,13 @@ function testDenormalize() {
     $bundle_uri = $schema->bundle('entity_test', 'entity_test')->getUri();
     $incoming_data = array(
       '@type' => $bundle_uri,
+      'user_id' => array(
+        'de' => array(
+          array(
+            '@id' => 'http://example.com/user/foo',
+          ),
+        ),
+      ),
       'name' => array(
         'en' => array(
           array(
@@ -167,12 +174,26 @@ function testDenormalize() {
       ),
     );
 
+    // Set the entity reference handlers for entity reference fields.
+    $values = array(
+      'targetEntityType' => 'entity_test',
+      'bundle' => 'entity_test',
+      'format' => static::$format,
+    );
+    $config = entity_create('entityreference_handler_settings', $values);
+    $config->setHandler('user_id', 'configured_value', array('value' => 1));
+    $config->save();
+
     // Test valid request.
     $entity = $this->normalizers['entity']->denormalize($incoming_data, 'Drupal\Core\Entity\EntityNG', static::$format);
     $this->assertEqual('entity_test', $entity->bundle(), "Denormalize creates entity with correct bundle.");
     $this->assertEqual($incoming_data['name']['en'], $entity->get('name')->getValue(), "Translatable field denormalized correctly in default language.");
     $this->assertEqual($incoming_data['name']['de'], $entity->getTranslation('de')->get('name')->getValue(), "Translatable field denormalized correctly in translation language.");
     $this->assertEqual($incoming_data['field_test_text']['und'], $entity->get('field_test_text')->getValue(), "Untranslatable field denormalized correctly.");
+    // For now, we just test that the user_id is equal to one.
+    // @todo Fix this once configured_value entity reference handler is
+    // enhanced.
+    $this->assertEqual(array(array('value' => 1)), $entity->getTranslation('de')->get('user_id')->getValue(), "Entity reference field denormalized correctly.");
 
     // Test request without @type.
     unset($incoming_data['@type']);
diff --git a/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php b/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php
index c5b298a..cb35d69 100644
--- a/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php
+++ b/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\rest\Tests;
 
+use Drupal\jsonld\Tests\JsonldTestSetupHelper;
 use Drupal\rest\Tests\RESTTestBase;
 
 /**
@@ -33,12 +34,16 @@ public static function getInfo() {
    * Tests several valid and invalid create requests on all entity types.
    */
   public function testCreate() {
-    $serializer = drupal_container()->get('serializer');
+    // Get the mock Serializer.
+    $jsonld_setup_helper = new JsonldTestSetupHelper();
+    $serializer = $jsonld_setup_helper->getSerializer();
+
     // @todo once EntityNG is implemented for other entity types test all other
     // entity types here as well.
     $entity_type = 'entity_test';
 
     $this->enableService('entity:' . $entity_type);
+    $this->setupEntityReferenceHandlers();
     // Create a user account that has the required permissions to create
     // resources via the web API.
     $account = $this->drupalCreateUser(array('restful post entity:' . $entity_type));
@@ -59,9 +64,6 @@ public function testCreate() {
     $loaded_entity = entity_load($entity_type, $id);
     $this->assertNotIdentical(FALSE, $loaded_entity, 'The new ' . $entity_type . ' was found in the database.');
     $this->assertEqual($entity->uuid(), $loaded_entity->uuid(), 'UUID of created entity is correct.');
-    // @todo Remove the user reference field for now until deserialization for
-    // entity references is implemented.
-    unset($entity_values['user_id']);
     foreach ($entity_values as $property => $value) {
       $actual_value = $loaded_entity->get($property)->value;
       $send_value = $entity->get($property)->value;
diff --git a/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php b/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php
index f7dbdb6..0d763fb 100644
--- a/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php
+++ b/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php
@@ -151,6 +151,21 @@ protected function entityValues($entity_type) {
   }
 
   /**
+   * Saves configuration for entity reference handlers for deserialization.
+   */
+  protected function setupEntityReferenceHandlers() {
+    // Set up the Entity Reference Handler for user_id field.
+    $values = array(
+      'targetEntityType' => 'entity_test',
+      'bundle' => 'entity_test',
+      'format' => 'drupal_jsonld',
+    );
+    $config = entity_create('entityreference_handler_settings', $values);
+    $config->setHandler('user_id', 'configured_value', array('value' => 1));
+    $config->save();
+  }
+
+  /**
    * Enables the web service interface for a specific entity type.
    *
    * @param string|FALSE $resource_type
diff --git a/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php b/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php
index fa65a2f..129d8e2 100644
--- a/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php
+++ b/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\rest\Tests;
 
+use Drupal\jsonld\Tests\JsonldTestSetupHelper;
 use Drupal\rest\Tests\RESTTestBase;
 
 /**
@@ -33,12 +34,15 @@ public static function getInfo() {
    * Tests several valid and invalid partial update requests on test entities.
    */
   public function testPatchUpdate() {
-    $serializer = drupal_container()->get('serializer');
+    // Get the mock Serializer.
+    $jsonld_setup_helper = new JsonldTestSetupHelper();
+    $serializer = $jsonld_setup_helper->getSerializer();
     // @todo once EntityNG is implemented for other entity types test all other
     // entity types here as well.
     $entity_type = 'entity_test';
 
     $this->enableService('entity:' . $entity_type);
+    $this->setupEntityReferenceHandlers();
     // Create a user account that has the required permissions to create
     // resources via the web API.
     $account = $this->drupalCreateUser(array('restful patch entity:' . $entity_type));
@@ -98,12 +102,15 @@ public function testPatchUpdate() {
    * Tests several valid and invalid PUT update requests on test entities.
    */
   public function testPutUpdate() {
-    $serializer = drupal_container()->get('serializer');
+    // Get the mock Serializer.
+    $jsonld_setup_helper = new JsonldTestSetupHelper();
+    $serializer = $jsonld_setup_helper->getSerializer();
     // @todo once EntityNG is implemented for other entity types test all other
     // entity types here as well.
     $entity_type = 'entity_test';
 
     $this->enableService('entity:' . $entity_type);
+    $this->setupEntityReferenceHandlers();
     // Create a user account that has the required permissions to create
     // resources via the web API.
     $account = $this->drupalCreateUser(array('restful put entity:' . $entity_type));
@@ -127,9 +134,6 @@ public function testPutUpdate() {
 
     // Re-load the updated entity from the database.
     $entity = entity_load($entity_type, $entity->id(), TRUE);
-    // @todo Don't check the user reference field for now until deserialization
-    // for entity references is implemented.
-    unset($update_values['user_id']);
     foreach ($update_values as $property => $value) {
       $update_value = $update_entity->{$property}->value;
       $stored_value = $entity->{$property}->value;
diff --git a/core/modules/rest/rest.info b/core/modules/rest/rest.info
index c0bf4bd..c450567 100644
--- a/core/modules/rest/rest.info
+++ b/core/modules/rest/rest.info
@@ -5,4 +5,5 @@ version = VERSION
 core = 8.x
 ; @todo Remove this dependency once hard coding to JSON-LD is gone.
 dependencies[] = jsonld
+dependencies[] = serialization
 configure = admin/config/services/rest
diff --git a/core/modules/serialization/lib/Drupal/serialization/Plugin/Core/Entity/EntityReferenceHandlerSettings.php b/core/modules/serialization/lib/Drupal/serialization/Plugin/Core/Entity/EntityReferenceHandlerSettings.php
new file mode 100644
index 0000000..f358d6a
--- /dev/null
+++ b/core/modules/serialization/lib/Drupal/serialization/Plugin/Core/Entity/EntityReferenceHandlerSettings.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * @file
+ * Contains Drupal/serialization/Plugin/Core/Entity/EntityReferenceHandlerSettings
+ */
+
+namespace Drupal\serialization\Plugin\Core\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * Configuration entity that contains display options for all components of a
+ * rendered entity in a given view mode..
+ *
+ * @Plugin(
+ *   id = "entityreference_handler_settings",
+ *   label = @Translation("Entity reference handler settings"),
+ *   module = "entity",
+ *   controller_class = "Drupal\Core\Config\Entity\ConfigStorageController",
+ *   config_prefix = "serialization.entityreference",
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "uuid" = "uuid"
+ *   }
+ * )
+ */
+class EntityReferenceHandlerSettings extends ConfigEntityBase {
+
+  /**
+   * Unique ID for the config entity.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * Unique UUID for the config entity.
+   *
+   * @var string
+   */
+  public $uuid;
+
+  /**
+   * Entity type to be deserialized.
+   *
+   * @var string
+   */
+  public $targetEntityType;
+
+  /**
+   * Bundle to be deserialized.
+   *
+   * @var string
+   */
+  public $bundle;
+
+  /**
+   * The short name of the serialization format.
+   *
+   * @var string
+   */
+  public $format;
+
+  /**
+   * List of entity reference field handlers, keyed by format and field name.
+   *
+   * @var array
+   */
+  public $entityreferenceHandlers = array();
+
+  /**
+   * Overrides \Drupal\Core\Entity\Entity::id().
+   */
+  public function id() {
+    return $this->targetEntityType . '.' . $this->bundle . '.' . $this->format;
+  }
+
+  /**
+   * Overrides \Drupal\config\ConfigEntityBase::save().
+   */
+  public function save() {
+    // Build an ID if none is set.
+    if (empty($this->id)) {
+      $this->id = $this->id();
+    }
+    return parent::save();
+  }
+
+  /**
+   * Sets the Entity Reference Handler to use when deserializing this field.
+   *
+   * @param $field_name
+   *   Name of the field which the handler will handle.
+   * @param $handler_name
+   *   The plugin id of the handler.
+   * @param $settings
+   *   The settings to use when creating a handler plugin instance.
+   */
+  public function setHandler($field_name, $handler_name, array $settings = array()) {
+    $this->entityreferenceHandlers[$field_name] = array(
+      'plugin_id' => $handler_name,
+      'settings' => $settings,
+    );
+  }
+
+  /**
+   * Gets the Entity Reference Handler to use when deserializing this field.
+   *
+   * @param $field_name
+   *   Name of the field which the handler will handle.
+   *
+   * @return string
+   *   The plugin id of the handler.
+   */
+  public function getHandler($field_name) {
+    if (isset($this->entityreferenceHandlers[$field_name])) {
+      return $this->entityreferenceHandlers[$field_name];
+    }
+    else {
+      // For now, return configured_value plugin whenever it isn't specified.
+      // @todo Make it possible to configure a default per format.
+      return array(
+        'plugin_id' => 'configured_value',
+        'settings' => array(
+          'value' => NULL,
+        )
+      );
+      //return FALSE;
+    }
+  }
+
+}
diff --git a/core/modules/serialization/lib/Drupal/serialization/Plugin/EntityReferenceHandlerBase.php b/core/modules/serialization/lib/Drupal/serialization/Plugin/EntityReferenceHandlerBase.php
new file mode 100644
index 0000000..5104269
--- /dev/null
+++ b/core/modules/serialization/lib/Drupal/serialization/Plugin/EntityReferenceHandlerBase.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\serialization\Plugin\EntityReferenceHandlerBase.
+ */
+
+namespace Drupal\serialization\Plugin;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\serialization\Plugin\EntityReferenceHandlerInterface;
+
+/**
+ * Base class for entity reference handlers.
+ */
+abstract class EntityReferenceHandlerBase extends PluginBase implements EntityReferenceHandlerInterface {
+
+  /**
+   * Whether default settings have been merged into the current $settings.
+   *
+   * @var bool
+   */
+  protected $defaultSettingsMerged = FALSE;
+
+  /**
+   * Returns the value of a setting, or its default value if absent.
+   *
+   * @param string $key
+   *   The setting name.
+   *
+   * @return mixed
+   *   The setting value.
+   */
+  public function getSetting($key) {
+    // Merge defaults if we have no value for the key.
+    if (!$this->defaultSettingsMerged && !array_key_exists($key, $this->configuration)) {
+      $this->mergeDefaults();
+    }
+    return isset($this->configuration[$key]) ? $this->configuration[$key] : NULL;
+  }
+
+  /**
+   * Merges default settings values into the configuration passed in.
+   */
+  protected function mergeDefaults() {
+    $this->configuration += $this->getDefaultSettings();
+    $this->defaultSettingsMerged = TRUE;
+  }
+
+  /**
+   * Returns the default settings for the plugin.
+   *
+   * @return array
+   *   The array of default setting values, keyed by setting names.
+   */
+  public function getDefaultSettings() {
+    $definition = $this->getDefinition();
+    return $definition['settings'];
+  }
+}
diff --git a/core/modules/serialization/lib/Drupal/serialization/Plugin/EntityReferenceHandlerInterface.php b/core/modules/serialization/lib/Drupal/serialization/Plugin/EntityReferenceHandlerInterface.php
new file mode 100644
index 0000000..fc2cf8c
--- /dev/null
+++ b/core/modules/serialization/lib/Drupal/serialization/Plugin/EntityReferenceHandlerInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\serialization\Plugin\EntityReferenceHandlerInterface;
+ */
+
+namespace Drupal\serialization\Plugin;
+
+/**
+ * Specifies the public methods of an entity reference handler plugin.
+ */
+interface EntityReferenceHandlerInterface {
+
+  /**
+   * Get the entity ID of the referenced entity.
+   *
+   * @return int
+   */
+  public function getEntityId($data, $format, $serializer);
+}
diff --git a/core/modules/serialization/lib/Drupal/serialization/Plugin/Type/EntityReferenceHandlerPluginManager.php b/core/modules/serialization/lib/Drupal/serialization/Plugin/Type/EntityReferenceHandlerPluginManager.php
new file mode 100644
index 0000000..02a01f2
--- /dev/null
+++ b/core/modules/serialization/lib/Drupal/serialization/Plugin/Type/EntityReferenceHandlerPluginManager.php
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal/serialization/Plugin/Type/EntityReferenceHandlerPluginManager
+ */
+
+namespace Drupal\serialization\Plugin\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+
+/**
+ * Defines the plugin manager for Entity Reference Handler plugins.
+ */
+class EntityReferenceHandlerPluginManager extends PluginManagerBase {
+
+  /**
+   * Overrides Drupal\Component\Plugin\PluginManagerBase::__construct().
+   */
+  public function __construct() {
+    $this->discovery = new AnnotatedClassDiscovery('serialization', 'entityreference_handler');
+    $this->factory = new DefaultFactory($this);
+  }
+}
diff --git a/core/modules/serialization/lib/Drupal/serialization/Plugin/serialization/entityreference_handler/ConfiguredValue.php b/core/modules/serialization/lib/Drupal/serialization/Plugin/serialization/entityreference_handler/ConfiguredValue.php
new file mode 100644
index 0000000..f0b5daa
--- /dev/null
+++ b/core/modules/serialization/lib/Drupal/serialization/Plugin/serialization/entityreference_handler/ConfiguredValue.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal/rest/Plugin/rest/entityreference_handler/ConfiguredValue
+ */
+
+namespace Drupal\serialization\Plugin\serialization\entityreference_handler;
+
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+use Drupal\serialization\Plugin\EntityReferenceHandlerBase;
+
+/**
+ * Provides an entity reference handler for using a configured value.
+ *
+ * @Plugin(
+ *   id = "configured_value",
+ *   label = @Translation("URI Dereference"),
+ *   settings = {
+ *     "value" = NULL
+ *   }
+ * )
+ */
+class ConfiguredValue extends EntityReferenceHandlerBase {
+
+  /**
+   * Implements EntityReferenceHandlerInterface::getEntityId()
+   */
+  public function getEntityId($data, $format, $serializer) {
+    return $this->getSetting('value');
+  }
+}
diff --git a/core/modules/serialization/lib/Drupal/serialization/Plugin/serialization/entityreference_handler/UriDereference.php b/core/modules/serialization/lib/Drupal/serialization/Plugin/serialization/entityreference_handler/UriDereference.php
new file mode 100644
index 0000000..cb6b9e6
--- /dev/null
+++ b/core/modules/serialization/lib/Drupal/serialization/Plugin/serialization/entityreference_handler/UriDereference.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal/rest/Plugin/rest/entityreference_handler/UriDereference
+ */
+
+namespace Drupal\serialization\Plugin\serialization\entityreference_handler;
+
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+use Drupal\serialization\Plugin\EntityReferenceHandlerBase;
+
+/**
+ * Provides an entity reference handler for dereferencing URIs.
+ *
+ * @Plugin(
+ *   id = "uri_dereference",
+ *   label = @Translation("URI Dereference"),
+ *   settings = {
+ *     "uri_key" = "uri"
+ *   }
+ * )
+ */
+class UriDereference extends EntityReferenceHandlerBase {
+  public function getEntityId($data, $format, $serializer) {
+    // Determine which attribute holds the URI.
+    $uri_key = $this->getSetting('uri_key');
+    // Get the data from that URI and decode it.
+    $response = $this->request($data[$uri_key], $format);
+    $response_data = $serializer->decode($response->getBody(TRUE), $format);
+
+    // @todo Being able to set the UUID like this depends on the UUID being a
+    // top level property in the entity representation. This might not be the
+    // case in some  formats. This would be handled by the Normalizer if we
+    // were using a recursive denormalization strategy.
+    $uuid = $response_data['uuid'];
+    while (is_array($uuid)) {
+      $uuid = reset($uuid);
+    }
+
+    $entity = entity_load_by_uuid($this->getSetting('target_entity_type'), $uuid);
+    return $entity->id();
+  }
+
+  protected function request($url, $format) {
+    $mimetype = drupal_container()->get('request')->getMimeType($format);
+    $request = drupal_container()->get('http_default_client')->get($url);
+    $request->setHeader('Accept', $mimetype);
+
+    try {
+      $response = $request->send();
+    }
+    catch (BadResponseException $e) {
+      // @todo Figure out what to do.
+    }
+    if ($response->getStatusCode() != 200) {
+      // @todo Figure out what to do.
+    }
+
+    return $response;
+  }
+}
diff --git a/core/modules/serialization/lib/Drupal/serialization/Plugin/serialization/entityreference_handler/Uuid.php b/core/modules/serialization/lib/Drupal/serialization/Plugin/serialization/entityreference_handler/Uuid.php
new file mode 100644
index 0000000..34b43f1
--- /dev/null
+++ b/core/modules/serialization/lib/Drupal/serialization/Plugin/serialization/entityreference_handler/Uuid.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\serialization\Plugin\serialization\entityreference_handler/Uuid
+ */
+
+namespace Drupal\serialization\Plugin\serialization\entityreference_handler;
+
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+use Drupal\serialization\Plugin\EntityReferenceHandlerBase;
+
+/**
+ * Provides an entity reference handler for matching based on UUID.
+ *
+ * @Plugin(
+ *   id = "uuid",
+ *   label = @Translation("URI Dereference"),
+ *   settings = {
+ *     "uuid_key" = "uuid"
+ *   }
+ * )
+ */
+class Uuid extends EntityReferenceHandlerBase {
+
+  /**
+   * Implements EntityReferenceHandlerInterface::getEntityId()
+   */
+  public function getEntityId($data, $format, $serializer) {
+    // Determine which attribute holds the UUID.
+    $uuid_key = $this->getSetting('uuid_key');
+    $uuid = $data[$uuid_key];
+    while (is_array($uuid)) {
+      $uuid = reset($uuid);
+    }
+
+    $entity = entity_load_by_uuid($this->getSetting('target_entity_type'), $uuid);
+    return $entity->id();
+  }
+
+}
diff --git a/core/modules/serialization/lib/Drupal/serialization/SerializationBundle.php b/core/modules/serialization/lib/Drupal/serialization/SerializationBundle.php
new file mode 100644
index 0000000..3ae938b
--- /dev/null
+++ b/core/modules/serialization/lib/Drupal/serialization/SerializationBundle.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\rest\SerializationBundle.
+ */
+
+namespace Drupal\serialization;
+
+use Drupal\Core\DependencyInjection\Compiler\RegisterSerializationClassesPass;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+/**
+ * Serialization dependency injection container.
+ */
+class SerializationBundle extends Bundle {
+
+  /**
+   * Overrides Symfony\Component\HttpKernel\Bundle\Bundle::build().
+   */
+  public function build(ContainerBuilder $container) {
+    // Register the entity reference handler plugin manager class.
+    $container->register('plugin.manager.serialization.entityreference_handler', 'Drupal\serialization\Plugin\Type\EntityReferenceHandlerPluginManager');
+    // Add Serializer with arguments to be replaced in the compiler pass.
+    $container->register('serializer', 'Symfony\Component\Serializer\Serializer')
+      ->addArgument(array())
+      ->addArgument(array());
+
+    $container->register('serializer.normalizer.complex_data', 'Drupal\Core\Serialization\ComplexDataNormalizer')->addTag('normalizer');
+    $container->register('serializer.normalizer.list', 'Drupal\Core\Serialization\ListNormalizer')->addTag('normalizer');
+    $container->register('serializer.normalizer.typed_data', 'Drupal\Core\Serialization\TypedDataNormalizer')->addTag('normalizer');
+
+    $container->register('serializer.encoder.json', 'Drupal\Core\Serialization\JsonEncoder')
+      ->addTag('encoder', array('format' => array('json' => 'JSON')));
+    $container->register('serializer.encoder.xml', 'Drupal\Core\Serialization\XmlEncoder')
+      ->addTag('encoder', array('format' => array('xml' => 'XML')));
+
+    // Add a compiler pass for adding Normalizers and Encoders to Serializer.
+    $container->addCompilerPass(new RegisterSerializationClassesPass());
+  }
+}
diff --git a/core/modules/serialization/lib/Drupal/serialization/Tests/EntityReferenceHandlerSettingsTest.php b/core/modules/serialization/lib/Drupal/serialization/Tests/EntityReferenceHandlerSettingsTest.php
new file mode 100644
index 0000000..26ca72e
--- /dev/null
+++ b/core/modules/serialization/lib/Drupal/serialization/Tests/EntityReferenceHandlerSettingsTest.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\serialization\Tests\EntityReferenceHandlerSettingsTest
+ */
+
+namespace Drupal\serialization\Tests;
+
+use Drupal\serialization\Plugin\serialization\entityreference_handler\ConfiguredValue;
+use Drupal\simpletest\DrupalUnitTestBase;
+
+class EntityReferenceHandlerSettingsTest extends DrupalUnitTestBase {
+
+  public static $modules = array('entity', 'serialization');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Entity Reference Deserialize Settings Test',
+      'description' => "Tests the Entity Reference Deserialize Settings config object.",
+      'group' => 'Serialization',
+    );
+  }
+
+  public function testSetGet() {
+    $values = array(
+      'targetEntityType' => 'entity_test',
+      'bundle' => 'entity_test',
+      'format' => 'drupal_jsonld',
+    );
+    $id = implode('.', $values);
+    $config = entity_create('entityreference_handler_settings', $values);
+    $config->setHandler('user_id', 'configured_value', array('value' => 1));
+    $config->save();
+
+    $loadedConfig = entity_load('entityreference_handler_settings', $id);
+    // Test that setHandler works.
+    $expected = array (
+      'user_id' => array(
+        'plugin_id' => 'configured_value',
+        'settings' => array(
+          'value' => 1,
+        ),
+      ),
+    );
+    $this->assertEqual($expected, $loadedConfig->get('entityreferenceHandlers'), 'setHandler() sets the appropriate handler.');
+
+    // Test that getHandler works.
+    $handler = $loadedConfig->getHandler('user_id');
+    $this->assertEqual($handler, $expected['user_id'], 'getHandler() returns the handler name.');
+  }
+}
diff --git a/core/modules/serialization/serialization.info b/core/modules/serialization/serialization.info
new file mode 100644
index 0000000..9ae7649
--- /dev/null
+++ b/core/modules/serialization/serialization.info
@@ -0,0 +1,4 @@
+name = Serialization
+description = Provides a service for (de)serializing data to/from formats such as JSON and XML
+package = Core
+core = 8.x
diff --git a/core/modules/serialization/serialization.module b/core/modules/serialization/serialization.module
new file mode 100644
index 0000000..fc57fb2
--- /dev/null
+++ b/core/modules/serialization/serialization.module
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Manage the serialization system.
+ *
+ * The module is mostly an anchor point for configuration items owned by the
+ * serialization system.
+ */
+
+/**
+ * Get the entity reference handler settings for a bundle in a format.
+ *
+ * @param $entity_type
+ *   The entity type of the bundle.
+ * @param $bundle
+ *   The bundle.
+ * @param $format
+ *   The format of the data being deserialzed.
+ *
+ * @return Drupal\serialization\Plugin\Core\Entity\EntityReferenceDeserializeSettings
+ *   The config object.
+ */
+function serialization_get_entityreference_handler_settings($entity_type, $bundle, $format) {
+  // Try loading the settings from configuration.
+  $settings = entity_load('entityreference_handler_settings', $entity_type . '.' . $bundle . '.' . $format);
+
+  // If not found, create a fresh config object.
+  if (!$settings) {
+    $settings = entity_create('entityreference_handler_settings', array(
+      'targetEntityType' => $entity_type,
+      'bundle' => $bundle,
+      'format' => $format,
+    ));
+  }
+
+  return $settings;
+}
\ No newline at end of file
diff --git a/core/modules/system/lib/Drupal/system/Tests/Serialization/EntitySerializationTest.php b/core/modules/system/lib/Drupal/system/Tests/Serialization/EntitySerializationTest.php
index 89fa5ce..97c6f29 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Serialization/EntitySerializationTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Serialization/EntitySerializationTest.php
@@ -23,7 +23,7 @@ class EntitySerializationTest extends WebTestBase {
    *
    * @var array
    */
-  public static $modules = array('entity_test');
+  public static $modules = array('entity_test', 'serialization');
 
   /**
    * The test values.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Serialization/SerializationTest.php b/core/modules/system/lib/Drupal/system/Tests/Serialization/SerializationTest.php
index 0a69208..425f0b0 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Serialization/SerializationTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Serialization/SerializationTest.php
@@ -17,12 +17,12 @@ class SerializationTest extends WebTestBase {
    *
    * @var array
    */
-  public static $modules = array('serialization_test');
+  public static $modules = array('serialization', 'serialization_test');
 
   /**
    * The serializer service to test.
    *
-   * @var Symfony\Component\Serializer\SerializerInterface
+   * @var \Symfony\Component\Serializer\SerializerInterface
    */
   protected $serializer;
 
diff --git a/core/modules/system/tests/modules/serialization_test/lib/Drupal/serialization_test/SerializationTestEncoder.php b/core/modules/system/tests/modules/serialization_test/lib/Drupal/serialization_test/SerializationTestEncoder.php
index edb3b5b..2f3896d 100644
--- a/core/modules/system/tests/modules/serialization_test/lib/Drupal/serialization_test/SerializationTestEncoder.php
+++ b/core/modules/system/tests/modules/serialization_test/lib/Drupal/serialization_test/SerializationTestEncoder.php
@@ -19,15 +19,7 @@ class SerializationTestEncoder implements EncoderInterface {
   static protected $format = 'serialization_test';
 
   /**
-   * Encodes data into the requested format.
-   *
-   * @param mixed $data
-   *   Data to encode.
-   * @param string $format
-   *   Format name.
-   *
-   * @return string
-   *   A string representation of $data in the requested format.
+   * Implements \Symfony\Component\Serializer\Encoder\EncoderInterface::encode().
    */
   public function encode($data, $format, array $context = array()) {
     // @see Drupal\serialization_test\SerializationTestNormalizer::normalize().
@@ -35,13 +27,7 @@ public function encode($data, $format, array $context = array()) {
   }
 
   /**
-   * Checks whether this encoder can encode to the requested format.
-   *
-   * @param string $format
-   *   The short name of the format.
-   *
-   * @return bool
-   *   Returns TRUE if this encoder can encode to the requested format.
+   * Implements \Symfony\Component\Serializer\Encoder\EncoderInterface::supportsEncoding().
    */
   public function supportsEncoding($format) {
     return static::$format === $format;
