diff --git a/core/lib/Drupal/Core/Field/Plugin/migrate/field/Email.php b/core/lib/Drupal/Core/Field/Plugin/migrate/field/Email.php
index af6229aeee..728b0a8c4d 100644
--- a/core/lib/Drupal/Core/Field/Plugin/migrate/field/Email.php
+++ b/core/lib/Drupal/Core/Field/Plugin/migrate/field/Email.php
@@ -32,10 +32,7 @@ public function getFieldWidgetMap() {
    */
   public function getFieldFormatterMap() {
     return [
-      'email_formatter_default' => 'basic_string',
-      'email_formatter_contact' => 'basic_string',
-      'email_formatter_plain' => 'basic_string',
-      'email_formatter_spamspan' => 'basic_string',
+      'email_default' => 'email_mailto',
     ];
   }
 
diff --git a/core/lib/Drupal/Core/Field/Plugin/migrate/field/d7/EntityReference.php b/core/lib/Drupal/Core/Field/Plugin/migrate/field/d7/EntityReference.php
index f45e95d2cc..eb04df8f07 100644
--- a/core/lib/Drupal/Core/Field/Plugin/migrate/field/d7/EntityReference.php
+++ b/core/lib/Drupal/Core/Field/Plugin/migrate/field/d7/EntityReference.php
@@ -15,4 +15,17 @@
  *   destination_module = "core"
  * )
  */
-class EntityReference extends FieldPluginBase {}
+class EntityReference extends FieldPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFieldFormatterMap() {
+    return [
+      'entityreference_label' => 'entity_reference_label',
+      'entityreference_entity_id' => 'entity_reference_entity_id',
+      'entityreference_entity_view' => 'entity_reference_entity_view',
+    ];
+  }
+
+}
diff --git a/core/modules/datetime/src/Plugin/migrate/field/DateField.php b/core/modules/datetime/src/Plugin/migrate/field/DateField.php
index a503fbbe6a..446076232f 100644
--- a/core/modules/datetime/src/Plugin/migrate/field/DateField.php
+++ b/core/modules/datetime/src/Plugin/migrate/field/DateField.php
@@ -24,6 +24,15 @@ class DateField extends FieldPluginBase {
   /**
    * {@inheritdoc}
    */
+  public function getFieldFormatterMap() {
+    return [
+      'date_default' => 'datetime_default',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getFieldWidgetMap() {
     return [
       'date' => 'datetime_default',
diff --git a/core/modules/field/migrations/d6_field_formatter_settings.yml b/core/modules/field/migrations/d6_field_formatter_settings.yml
index fc97ad0225..63739342ea 100644
--- a/core/modules/field/migrations/d6_field_formatter_settings.yml
+++ b/core/modules/field/migrations/d6_field_formatter_settings.yml
@@ -172,7 +172,7 @@ process:
             default: entity_reference_label
             plain: entity_reference_label
       -
-        plugin: field_type_defaults
+        plugin: d6_field_type_defaults
   "options/settings":
     -
       plugin: static_map
diff --git a/core/modules/field/migrations/d7_field_formatter_settings.yml b/core/modules/field/migrations/d7_field_formatter_settings.yml
index 5c9335ca86..dd444f8397 100644
--- a/core/modules/field/migrations/d7_field_formatter_settings.yml
+++ b/core/modules/field/migrations/d7_field_formatter_settings.yml
@@ -54,6 +54,11 @@ process:
   field_name: field_name
   "options/label": 'formatter/label'
   "options/weight": 'formatter/weight'
+  # The field plugin ID.
+  plugin_id:
+    plugin: process_field
+    source: type
+    method: getPluginId
   # The formatter to use.
   formatter_type:
     plugin: process_field
@@ -63,19 +68,14 @@ process:
     -
       plugin: static_map
       bypass: true
-      source: '@formatter_type'
-      map:
-        date_default: datetime_default
-        email_default: email_mailto
-        # 0 should cause the row to be skipped by the next plugin in the
-        # pipeline.
-        hidden: 0
-        link_default: link
-        phone: basic_string
-        taxonomy_term_reference_link: entity_reference_label
-        entityreference_label: entity_reference_label
-        entityreference_entity_id: entity_reference_entity_id
-        entityreference_entity_view: entity_reference_entity_view
+      source:
+        - '@plugin_id'
+        - '@formatter_type'
+      # The map is generated by the getFieldFormatterMap() method from the
+      # migrate field plugins.
+      map: []
+    -
+      plugin: d7_field_type_defaults
     -
       plugin: skip_on_empty
       method: row
diff --git a/core/modules/field/src/Plugin/migrate/process/FieldTypeDefaults.php b/core/modules/field/src/Plugin/migrate/process/FieldTypeDefaults.php
new file mode 100644
index 0000000000..d43b6a4069
--- /dev/null
+++ b/core/modules/field/src/Plugin/migrate/process/FieldTypeDefaults.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Drupal\field\Plugin\migrate\process;
+
+use Drupal\field\Plugin\migrate\process\d6\FieldTypeDefaults as D6FieldTypeDefaults;
+
+/**
+ * BC Layer.
+ *
+ * @MigrateProcessPlugin(
+ *   id = "field_type_defaults"
+ * )
+ */
+class FieldTypeDefaults extends D6FieldTypeDefaults {}
diff --git a/core/modules/field/src/Plugin/migrate/process/d6/FieldTypeDefaults.php b/core/modules/field/src/Plugin/migrate/process/d6/FieldTypeDefaults.php
index 869e9b66ef..50d4e924a8 100644
--- a/core/modules/field/src/Plugin/migrate/process/d6/FieldTypeDefaults.php
+++ b/core/modules/field/src/Plugin/migrate/process/d6/FieldTypeDefaults.php
@@ -11,7 +11,7 @@
  * Gives us a chance to set per field defaults.
  *
  * @MigrateProcessPlugin(
- *   id = "field_type_defaults"
+ *   id = "d6_field_type_defaults"
  * )
  */
 class FieldTypeDefaults extends ProcessPluginBase {
diff --git a/core/modules/field/src/Plugin/migrate/process/d7/FieldTypeDefaults.php b/core/modules/field/src/Plugin/migrate/process/d7/FieldTypeDefaults.php
new file mode 100644
index 0000000000..8a7267d235
--- /dev/null
+++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldTypeDefaults.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Drupal\field\Plugin\migrate\process\d7;
+
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\Row;
+
+/**
+ * Gives us a chance to set per field defaults.
+ *
+ * @MigrateProcessPlugin(
+ *   id = "d7_field_type_defaults"
+ * )
+ */
+class FieldTypeDefaults extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    if (is_array($value) && isset($value[1])) {
+      return $value[1];
+    }
+    return $value;
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldTypeDefaultsTest.php b/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldTypeDefaultsTest.php
new file mode 100644
index 0000000000..eb080c8410
--- /dev/null
+++ b/core/modules/field/tests/src/Unit/Plugin/migrate/process/d7/FieldTypeDefaultsTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Drupal\Tests\field\Unit\Plugin\migrate\process\d7;
+
+use Drupal\field\Plugin\migrate\process\d7\FieldTypeDefaults;
+use Drupal\Tests\migrate\Unit\process\MigrateProcessTestCase;
+
+/**
+ * Tests D7 field formatter defaults.
+ *
+ * @coversDefaultClass \Drupal\field\Plugin\migrate\process\d7\FieldTypeDefaults
+ * @group field
+ */
+class FieldTypeDefaultsTest extends MigrateProcessTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->plugin = new FieldTypeDefaults([], 'd7_field_type_defaults', []);
+  }
+
+  /**
+   * Tests various default cases.
+   *
+   * @covers ::transform
+   */
+  public function testDefaults() {
+    // Assert common values are passed through without modification.
+    $this->assertNull($this->plugin->transform(NULL, $this->migrateExecutable, $this->row, 'property'));
+    $this->assertEquals('string', $this->plugin->transform('string', $this->migrateExecutable, $this->row, 'property'));
+    $this->assertEquals(1234, $this->plugin->transform(1234, $this->migrateExecutable, $this->row, 'property'));
+    // Assert that an array will return the second item, which is the source
+    // formatter type.
+    $this->assertEquals('datetime_default', $this->plugin->transform(['datetime', 'datetime_default'], $this->migrateExecutable, $this->row, 'property'));
+  }
+
+}
diff --git a/core/modules/link/src/Plugin/migrate/field/d7/LinkField.php b/core/modules/link/src/Plugin/migrate/field/d7/LinkField.php
index 0dcf4c64c5..c9c7f9f188 100644
--- a/core/modules/link/src/Plugin/migrate/field/d7/LinkField.php
+++ b/core/modules/link/src/Plugin/migrate/field/d7/LinkField.php
@@ -25,6 +25,15 @@ class LinkField extends D6LinkField {
   /**
    * {@inheritdoc}
    */
+  public function getFieldFormatterMap() {
+    return [
+      'link_default' => 'link',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getFieldWidgetMap() {
     // By default, use the plugin ID for the widget types.
     return ['link_field' => 'link_default'];
diff --git a/core/modules/taxonomy/src/Plugin/migrate/field/TaxonomyTermReference.php b/core/modules/taxonomy/src/Plugin/migrate/field/TaxonomyTermReference.php
index 2f41e51a7c..bea9a3f95f 100644
--- a/core/modules/taxonomy/src/Plugin/migrate/field/TaxonomyTermReference.php
+++ b/core/modules/taxonomy/src/Plugin/migrate/field/TaxonomyTermReference.php
@@ -21,6 +21,15 @@ class TaxonomyTermReference extends FieldPluginBase {
   /**
    * {@inheritdoc}
    */
+  public function getFieldFormatterMap() {
+    return [
+      'taxonomy_term_reference_link' => 'entity_reference_label',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function processFieldValues(MigrationInterface $migration, $field_name, $data) {
     $process = [
       'plugin' => 'sub_process',
diff --git a/core/modules/telephone/src/Plugin/migrate/field/d7/PhoneField.php b/core/modules/telephone/src/Plugin/migrate/field/d7/PhoneField.php
index d98f344344..4a9d8cd4e0 100644
--- a/core/modules/telephone/src/Plugin/migrate/field/d7/PhoneField.php
+++ b/core/modules/telephone/src/Plugin/migrate/field/d7/PhoneField.php
@@ -15,4 +15,15 @@
  *   destination_module = "telephone"
  * )
  */
-class PhoneField extends FieldPluginBase {}
+class PhoneField extends FieldPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFieldFormatterMap() {
+    return [
+      'phone' => 'basic_string',
+    ];
+  }
+
+}
