diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index e70b1fc62c6b26a2f1d1274fe2d9e3d0bff40c91..bc6afef4267a7e9e665e81a3a08458213b5c4112 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -254,6 +254,7 @@ public function build(ContainerBuilder $container) {
     $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');
+    $container->register('serializer.encoder.xml', 'Drupal\Core\Serialization\XmlEncoder')->addTag('encoder');
 
     $container->register('flood', 'Drupal\Core\Flood\DatabaseBackend')
       ->addArgument(new Reference('database'));
diff --git a/core/lib/Drupal/Core/Serialization/XmlEncoder.php b/core/lib/Drupal/Core/Serialization/XmlEncoder.php
new file mode 100644
index 0000000000000000000000000000000000000000..7235af3aa7a60aeea7cbf7d9c3056b0e9c900339
--- /dev/null
+++ b/core/lib/Drupal/Core/Serialization/XmlEncoder.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Serialization\XmlEncoder.
+ */
+
+namespace Drupal\Core\Serialization;
+
+use Symfony\Component\Serializer\Encoder\EncoderInterface;
+use Symfony\Component\Serializer\Encoder\DecoderInterface;
+use Symfony\Component\Serializer\Encoder\SerializerAwareEncoder;
+use Symfony\Component\Serializer\Encoder\XmlEncoder as BaseXmlEncoder;
+
+/**
+ * Adds XML support for serializer.
+ *
+ * This acts as a wrapper class for Symfony's XmlEncoder so that it is not
+ * implementing NormalizationAwareInterface, and can be normalized externally.
+ */
+class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, DecoderInterface {
+
+  /**
+   * The formats that this Encoder supports.
+   *
+   * @var array
+   */
+  static protected $format = array('xml');
+
+  /**
+   * An instance of the Symfony XmlEncoder to perform the actual encoding.
+   *
+   * @var \Symfony\Component\Serializer\Encoder\XmlEncoder
+   */
+  protected $baseEncoder;
+
+  /**
+   * Constucts the XmlEncoder object, creating a BaseXmlEncoder class also.
+   */
+  public function __construct() {
+    $this->baseEncoder = new BaseXmlEncoder();
+  }
+
+  /**
+   * Implements \Symfony\Component\Serializer\Encoder\EncoderInterface::encode().
+   */
+  public function encode($data, $format){
+    $normalized = $this->serializer->normalize($data, $format);
+    return $this->baseEncoder->encode($normalized, $format);
+  }
+
+  /**
+   * Implements \Symfony\Component\Serializer\Encoder\JsonEncoder::supportsEncoding().
+   */
+  public function supportsEncoding($format) {
+    return in_array($format, static::$format);
+  }
+
+  /**
+   * Implements \Symfony\Component\Serializer\Encoder\EncoderInterface::decode().
+   */
+  public function decode($data, $format){
+    return $this->baseEncoder->decode($data, $format);
+  }
+
+  /**
+   * Implements \Symfony\Component\Serializer\Encoder\JsonEncoder::supportsDecoding().
+   */
+  public function supportsDecoding($format) {
+    return in_array($format, static::$format);
+  }
+}
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 ea3c9603989164d0b98c7a1d290550249f7baaba..89fa5ce0b85608dacf794c99055515803519b9ff 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Serialization/EntitySerializationTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Serialization/EntitySerializationTest.php
@@ -120,9 +120,38 @@ public function testSerialize() {
     $expected = json_encode($normalized);
     // Test 'json'.
     $actual = $serializer->serialize($this->entity, 'json');
-    $this->assertIdentical($actual, $expected, 'Entity serializes to JSON when json is requested.');
+    $this->assertIdentical($actual, $expected, 'Entity serializes to JSON when "json" is requested.');
+    $actual = $serializer->serialize($normalized, 'json');
+    $this->assertIdentical($actual, $expected, 'A normalized array serializes to JSON when "json" is requested');
     // Test 'ajax'.
     $actual = $serializer->serialize($this->entity, 'ajax');
-    $this->assertIdentical($actual, $expected, 'Entity serializes to JSON when ajax is requested.');
+    $this->assertIdentical($actual, $expected, 'Entity serializes to JSON when "ajax" is requested.');
+    $actual = $serializer->serialize($normalized, 'ajax');
+    $this->assertIdentical($actual, $expected, 'A normalized array serializes to JSON when "ajax" is requested');
+
+    // Generate the expected xml in a way that allows changes to entity property
+    // order.
+    $expected = array(
+      'id' => '<id><value>' . $this->entity->id() . '</value></id>',
+      'revision_id' => '<revision_id><value>' . $this->entity->getRevisionId() . '</value></revision_id>',
+      'uuid' => '<uuid><value>' . $this->entity->uuid() . '</value></uuid>',
+      'langcode' => '<langcode><value>' . LANGUAGE_NOT_SPECIFIED . '</value></langcode>',
+      'default_langcode' => '<default_langcode><value/></default_langcode>',
+      'name' => '<name><value>' . $this->values['name'] . '</value></name>',
+      'user_id' => '<user_id><value>' . $this->values['user_id'] . '</value></user_id>',
+      'field_test_text' => '<field_test_text><value>' . $this->values['field_test_text']['value'] . '</value><format>' . $this->values['field_test_text']['format'] . '</format></field_test_text>',
+    );
+    // Sort it in the same order as normalised.
+    $expected = array_merge($normalized, $expected);
+    // Add header and footer.
+    array_unshift($expected, '<?xml version="1.0"?>' . PHP_EOL . '<response>');
+    $expected[] = '</response>' . PHP_EOL;
+    // Reduced the array to a string.
+    $expected = implode('', $expected);
+    // Test 'xml'. The output should match that of Symfony's XmlEncoder.
+    $actual = $serializer->serialize($this->entity, 'xml');
+    $this->assertIdentical($actual, $expected);
+    $actual = $serializer->serialize($normalized, 'xml');
+    $this->assertIdentical($actual, $expected);
   }
 }