diff --git a/metatag.services.yml b/metatag.services.yml
index 46d3d42..01e5393 100644
--- a/metatag.services.yml
+++ b/metatag.services.yml
@@ -14,6 +14,12 @@ services:
   metatag.manager:
     class: Drupal\metatag\MetatagManager
     arguments: ['@plugin.manager.metatag.group', '@plugin.manager.metatag.tag', '@metatag.token', '@logger.factory']
+
+  metatag.normalizer.metatagfielditem:
+    class: Drupal\metatag\Normalizer\FieldItemNormalizer
+    tags:
+      - { name: normalizer, priority: 30 }
+
   metatag_generate_group:
     class: Drupal\metatag\Command\GenerateGroupCommand
     tags:
diff --git a/src/Normalizer/FieldItemNormalizer.php b/src/Normalizer/FieldItemNormalizer.php
new file mode 100644
index 0000000..69c0b6e
--- /dev/null
+++ b/src/Normalizer/FieldItemNormalizer.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\metatag\Normalizer\FieldItemNormalizer.
+ */
+
+namespace Drupal\metatag\Normalizer;
+
+use Drupal\Core\Field\FieldItemInterface;
+use Symfony\Component\Serializer\Exception\InvalidArgumentException;
+use Drupal\serialization\Normalizer\NormalizerBase;
+
+/**
+ * Converts the Metatag field item object structure to METATAG array structure.
+ */
+class FieldItemNormalizer extends NormalizerBase {
+
+  /**
+   * The interface or class that this Normalizer supports.
+   *
+   * @var string
+   */
+  protected $supportedInterfaceOrClass = 'Drupal\metatag\Plugin\Field\FieldType\MetatagFieldItem';
+
+  /**
+   * Implements \Symfony\Component\Serializer\Normalizer\NormalizerInterface::normalize()
+   */
+  public function normalize($field_item, $format = NULL, array $context = []) {
+    $values = $field_item->toArray();
+
+    // Convert tokens if there are any.
+    $token = \Drupal::token();
+    $values['value'] = $token->replace($values['value']);
+
+    if (isset($context['langcode'])) {
+      $values['lang'] = $context['langcode'];
+    }
+
+    // Detect any data format that could be JSON (since we can define our own).
+    if (strpos($format, 'json') !== false) {
+      $tags = [];
+      // Get serialized value and break it into an array of tags with values.
+      $serialized_value = $field_item->get('value')->getValue();
+      $tags += unserialize($serialized_value);
+    }
+
+    // Convert tokens if there are any.
+    $tags = array_map(function ($s) {
+      $token = \Drupal::token();
+      return $token->replace($s);
+    }, $tags);
+
+    // Mock the field array similar to the other fields.
+    return array(
+      $field_item->getfieldDefinition()->getName() => [
+        [
+          // Kept for backwards compatibility.
+          'value' => $values['value'],
+          'values' => $tags,
+          'lang' => $values['lang']
+        ]
+      ]
+    );
+  }
+}
