diff --git a/core/modules/migrate/src/Entity/Migration.php b/core/modules/migrate/src/Entity/Migration.php
index ba563f1..78a0605 100644
--- a/core/modules/migrate/src/Entity/Migration.php
+++ b/core/modules/migrate/src/Entity/Migration.php
@@ -14,6 +14,7 @@
 use Drupal\migrate\MigrateSkipRowException;
 use Drupal\migrate\Plugin\MigrateIdMapInterface;
 use Drupal\migrate\Plugin\RequirementsInterface;
+use Drupal\Component\Utility\NestedArray;
 
 /**
  * Defines the Migration entity.
@@ -406,6 +407,29 @@ public function setProcess(array $process) {
   /**
    * {@inheritdoc}
    */
+  public function setProcessOfProperty($field_name, $process) {
+    $this->process[$field_name] = $process;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function mergeProcessOfProperty($field_name, array $process) {
+    // If we already have a process value then merge the incoming process array
+    //otherwise simply set it.
+    if (isset($this->process[$field_name])) {
+      $this->process = NestedArray::mergeDeepArray([$this->process, [$field_name => $process]], TRUE);
+    }
+    else {
+      $this->setProcessOfProperty($field_name, $process);
+    }
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getSystemOfRecord() {
     return $this->systemOfRecord;
   }
diff --git a/core/modules/migrate/src/Entity/MigrationInterface.php b/core/modules/migrate/src/Entity/MigrationInterface.php
index 09cc770..fc575a2 100644
--- a/core/modules/migrate/src/Entity/MigrationInterface.php
+++ b/core/modules/migrate/src/Entity/MigrationInterface.php
@@ -198,6 +198,36 @@ public function getProcess();
   public function setProcess(array $process);
 
   /**
+   * Set the process for an individual destination field.
+   *
+   * @param string $field_name
+   *   The field name of which to set the process.
+   * @param mixed $process
+   *   A valid process value, array or string.
+   *
+   * @return $this
+   *   The migration entity.
+   *
+   * @see Drupal\migrate_drupal\Plugin\migrate\load\LoadEntity::processLinkField().
+   */
+  public function setProcessOfProperty($field_name, $process);
+
+  /**
+   * Merge the process arrays for an individual field.
+   *
+   * @param string $field_name
+   *   The field name of which to set the process.
+   * @param array $process
+   *   An array of process data.
+   *
+   * @return $this
+   *   The migration entity.
+   *
+   * @see Drupal\migrate_drupal\Plugin\migrate\load\LoadEntity::processLinkField().
+   */
+  public function mergeProcessOfProperty($field_name, array $process);
+
+  /**
    * Get the current system of record of the migration.
    *
    * @return string
diff --git a/core/modules/migrate/src/Plugin/MigratePluginManager.php b/core/modules/migrate/src/Plugin/MigratePluginManager.php
index 67cce89..f6eee47 100644
--- a/core/modules/migrate/src/Plugin/MigratePluginManager.php
+++ b/core/modules/migrate/src/Plugin/MigratePluginManager.php
@@ -46,13 +46,6 @@ class MigratePluginManager extends DefaultPluginManager {
    *   The annotation class name.
    */
   public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, $annotation = 'Drupal\Component\Annotation\PluginID') {
-    $plugin_interface_map = array(
-      'destination' => 'Drupal\migrate\Plugin\MigrateDestinationInterface',
-      'process' => 'Drupal\migrate\Plugin\MigrateProcessInterface',
-      'source' => 'Drupal\migrate\Plugin\MigrateSourceInterface',
-      'id_map' => 'Drupal\migrate\Plugin\MigrateIdMapInterface',
-      'entity_field' => 'Drupal\migrate\Plugin\MigrateEntityDestinationFieldInterface',
-    );
     $plugin_interface = isset($plugin_interface_map[$type]) ? $plugin_interface_map[$type] : NULL;
     parent::__construct("Plugin/migrate/$type", $namespaces, $module_handler, $plugin_interface, $annotation);
     $this->alterInfo('migrate_' . $type . '_info');
@@ -77,4 +70,20 @@ public function createInstance($plugin_id, array $configuration = array(), Migra
     return $plugin;
   }
 
+  /**
+   * Helper for the plugin type to interface map.
+   *
+   * @return array
+   *   An array map from plugin type to interface.
+   */
+  protected function getPluginInterfaceMap() {
+    return [
+      'destination' => 'Drupal\migrate\Plugin\MigrateDestinationInterface',
+      'process' => 'Drupal\migrate\Plugin\MigrateProcessInterface',
+      'source' => 'Drupal\migrate\Plugin\MigrateSourceInterface',
+      'id_map' => 'Drupal\migrate\Plugin\MigrateIdMapInterface',
+      'entity_field' => 'Drupal\migrate\Plugin\MigrateEntityDestinationFieldInterface',
+    ];
+  }
+
 }
diff --git a/core/modules/migrate_drupal/migrate_drupal.services.yml b/core/modules/migrate_drupal/migrate_drupal.services.yml
index 2c8f00c..301ced8 100644
--- a/core/modules/migrate_drupal/migrate_drupal.services.yml
+++ b/core/modules/migrate_drupal/migrate_drupal.services.yml
@@ -2,3 +2,6 @@ services:
   plugin.manager.migrate.load:
     class: Drupal\migrate_drupal\Plugin\MigratePluginManager
     arguments: [load, '@container.namespaces', '@cache.discovery', '@module_handler']
+  plugin.manager.migrate.cckfield:
+    class: Drupal\migrate_drupal\Plugin\MigratePluginManager
+    arguments: [cckfield, '@container.namespaces', '@cache.discovery', '@module_handler']
diff --git a/core/modules/migrate_drupal/src/MigrationStorage.php b/core/modules/migrate_drupal/src/MigrationStorage.php
index 28afe63..43509fe 100644
--- a/core/modules/migrate_drupal/src/MigrationStorage.php
+++ b/core/modules/migrate_drupal/src/MigrationStorage.php
@@ -10,6 +10,8 @@
 use Drupal\Component\Utility\String;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityStorageException;
+use Drupal\migrate_drupal\Plugin\CckFieldMigrateSourceInterface;
+use Drupal\migrate\Entity\MigrationInterface;
 use Drupal\migrate\MigrationStorage as BaseMigrationStorage;
 
 /**
@@ -18,6 +20,18 @@
 class MigrationStorage extends BaseMigrationStorage {
 
   /**
+   * A cached array of cck field plugins.
+   *
+   * @var array
+   */
+  protected $cckFieldPlugins;
+
+  /**
+   * @var \Drupal\migrate_drupal\Plugin\MigratePluginManager
+   */
+  protected $cckPluginManager;
+
+  /**
    * {@inheritdoc}
    */
   public function loadMultiple(array $ids = NULL) {
@@ -82,6 +96,10 @@ public function loadMultiple(array $ids = NULL) {
       }
     }
 
+    // Allow modules providing cck field plugins to alter the required
+    // migrations for successfully migration a field type.
+    $this->applyCckFieldProcessors($entities);
+
     // Build an array of dependencies and set the order of the migrations.
     return $this->buildDependencyMigration($entities, $dynamic_ids);
   }
@@ -111,4 +129,86 @@ public function save(EntityInterface $entity) {
     return parent::save($entity);
   }
 
+  /**
+   * Allow any field type plugins to adjust the migrations as required.
+   *
+   * @param array $entities
+   *   An array of migration entities.
+   */
+  protected function applyCckFieldProcessors(array $entities) {
+    /** @var \Drupal\migrate\Entity\Migration $migration */
+    foreach ($entities as $entity_id => $migration) {
+
+      // Allow field plugins to process the required migrations.
+      foreach ($this->getCckFieldPlugins() as $plugin) {
+        if ($method = $this->getMigrationPluginMethod($entity_id)) {
+          $plugin->$method($migration);
+        }
+      }
+
+      // If this is a CCK bundle migration, allow the cck field plugins to add
+      // any field type processing.
+      $source_plugin = $migration->getSourcePlugin();
+      if ($source_plugin instanceof CckFieldMigrateSourceInterface) {
+        $plugins = $this->getCckFieldPlugins();
+        foreach ($source_plugin->fieldData() as $field_name => $data) {
+          if (isset($plugins[$data['type']])) {
+            $plugins[$data['type']]->processCckFieldValues($migration, $field_name, $data);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Get an array of loaded cck field plugins.
+   *
+   * @return \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface[]
+   *   An array of cck field process plugins.
+   */
+  protected function getCckFieldPlugins() {
+    if (!isset($this->cckFieldPlugins)) {
+      $this->cckFieldPlugins = [];
+      foreach ($this->getCckPluginManager()->getDefinitions() as $definition) {
+        $this->cckFieldPlugins[$definition['id']] = $this->getCckPluginManager()->createInstance($definition['id']);
+      }
+    }
+    return $this->cckFieldPlugins;
+  }
+
+  /**
+   * Provides a map between migration ids and the cck field plugin method.
+   *
+   * @param string $entity_id
+   *   The migration entity id.
+   *
+   * @return bool|string
+   *   The method to call on the processing plugin or FALSE.
+   */
+  protected function getMigrationPluginMethod($entity_id) {
+    $map = [
+      'd6_field' => 'processField',
+      'd6_field_instance_widget_settings' => 'processFieldWidget',
+      'd6_field_formatter_settings' => 'processFieldDisplay',
+    ];
+    if (isset($map[$entity_id])) {
+      return $map[$entity_id];
+    }
+
+    return FALSE;
+  }
+
+  /**
+   * Get the cck field plugin manager.
+   *
+   * @return \Drupal\migrate_drupal\Plugin\MigratePluginManager
+   *   The loaded plugin manager.
+   */
+  protected function getCckPluginManager() {
+    if (!isset($this->cckPluginManager)) {
+      $this->cckPluginManager = \Drupal::service('plugin.manager.migrate.cckfield');
+    }
+    return $this->cckPluginManager;
+  }
+
 }
diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php
new file mode 100644
index 0000000..2cb59a7
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface
+ */
+
+namespace Drupal\migrate_drupal\Plugin;
+
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\migrate\Entity\MigrationInterface;
+
+/**
+ * Provides an interface for all CCK field type plugins.
+ */
+interface MigrateCckFieldInterface extends PluginInspectionInterface {
+
+  /**
+   * Apply any custom processing to the field migration.
+   *
+   * @param \Drupal\migrate\Entity\MigrationInterface $migration
+   *   The migration entity.
+   */
+  public function processField(MigrationInterface $migration);
+
+  /**
+   * Apply any custom processing to the field widget migration.
+   *
+   * @param \Drupal\migrate\Entity\MigrationInterface $migration
+   *   The migration entity.
+   */
+  public function processFieldWidget(MigrationInterface $migration);
+
+  /**
+   * Apply any custom processing to the field display migration.
+   *
+   * @param \Drupal\migrate\Entity\MigrationInterface $migration
+   *   The migration entity.
+   */
+  public function processFieldDisplay(MigrationInterface $migration);
+
+  /**
+   * Get a map between D6 formatters and D8 formatters for this field type.
+   *
+   * This is used by static::processFieldDisplay() in the base class.
+   *
+   * @return array
+   *   The keys are D6 formatters and the values are D8 formatters.
+   */
+  public function getFieldDisplayMap();
+
+  /**
+   * Apply any custom processing to the cck bundle migrations.
+   *
+   * @param \Drupal\migrate\Entity\MigrationInterface $migration
+   *   The migration entity.
+   */
+  public function processCckFieldValues(MigrationInterface $migration, $field_name, $data);
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/MigratePluginManager.php b/core/modules/migrate_drupal/src/Plugin/MigratePluginManager.php
index c93ff07..4a15e77 100644
--- a/core/modules/migrate_drupal/src/Plugin/MigratePluginManager.php
+++ b/core/modules/migrate_drupal/src/Plugin/MigratePluginManager.php
@@ -7,9 +7,6 @@
 
 namespace Drupal\migrate_drupal\Plugin;
 
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Plugin\Factory\ContainerFactory;
 use Drupal\migrate\Plugin\MigratePluginManager as BaseMigratePluginManager;
 
 /**
@@ -24,11 +21,11 @@ class MigratePluginManager extends BaseMigratePluginManager {
   /**
    * {@inheritdoc}
    */
-  public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, $annotation = 'Drupal\Component\Annotation\PluginID') {
-    parent::__construct($type, $namespaces, $cache_backend, $module_handler, $annotation);
-
-    $this->factory = new ContainerFactory($this, 'Drupal\migrate_drupal\Plugin\MigrateLoadInterface');
+  protected function getPluginInterfaceMap() {
+    return parent::getPluginInterfaceMap() + [
+      'load' => 'Drupal\migrate_drupal\Plugin\MigrateLoadInterface',
+      'cckfield' => 'Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface',
+    ];
   }
 
-
 }
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/cckfield/CckFieldPluginBase.php b/core/modules/migrate_drupal/src/Plugin/migrate/cckfield/CckFieldPluginBase.php
new file mode 100644
index 0000000..561b761
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/cckfield/CckFieldPluginBase.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Plugin\migrate\cckfield\MigrateCckFieldInterface.
+ */
+
+namespace Drupal\migrate_drupal\Plugin\migrate\cckfield;
+
+use Drupal\Core\Plugin\PluginBase;
+use Drupal\migrate\Entity\MigrationInterface;
+use Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface;
+
+/**
+ * The base class for all cck field plugins.
+ *
+ * @see \Drupal\migrate_drupal\Plugin\MigratePluginManager
+ * @see \Drupal\migrate_drupal\Annotation\MigrateCckField
+ * @see \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface
+ * @see plugin_api
+ *
+ * @ingroup migration
+ */
+abstract class CckFieldPluginBase extends PluginBase implements MigrateCckFieldInterface  {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processField(MigrationInterface $migration) {
+    $process[0]['map'][$this->pluginId][$this->pluginId] = $this->pluginId;
+    $migration->mergeProcessOfProperty('type', $process);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processFieldWidget(MigrationInterface $migration) {
+    $process['type']['map'][$this->pluginId] = $this->pluginId . '_default';
+    $migration->mergeProcessOfProperty('options/type', $process);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processFieldDisplay(MigrationInterface $migration) {
+    $process = [];
+    foreach ($this->getFieldDisplayMap() as $source_format => $destination_format) {
+      $process[0]['map'][$this->pluginId][$source_format] = $destination_format;
+    }
+    $migration->mergeProcessOfProperty('options/type', $process);
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/load/LoadEntity.php b/core/modules/migrate_drupal/src/Plugin/migrate/load/LoadEntity.php
index c9db0e7..f04672d 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/load/LoadEntity.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/load/LoadEntity.php
@@ -98,9 +98,7 @@ public function loadMultiple(EntityStorageInterface $storage, array $sub_ids = N
                 $this->processTextField($field_name, $data, $migration);
                 break;
               default:
-                $process = $migration->getProcess();
-                $process[$field_name] = $field_name;
-                $migration->setProcess($process);
+                $migration->setProcessOfProperty($field_name, $field_name);
             }
           }
         }
@@ -134,12 +132,11 @@ protected function processTextField($field_name, $field_data, MigrationInterface
     $value_key = $field_data['db_storage'] ? $field_name : "$field_name/value";
     $format_key = $field_data['db_storage'] ? $field_name . '_format' : "$field_name/format" ;
 
-    $process = $migration->getProcess();
+    $migration->setProcessOfProperty("$field_name/value", $value_key);
 
-    $process["$field_name/value"] = $value_key;
     // See d6_user, signature_format for an example of the YAML that
     // represents this process array.
-    $process["$field_name/format"] = [
+    $process = [
       [
         'plugin' => 'static_map',
         'bypass' => TRUE,
@@ -153,8 +150,7 @@ protected function processTextField($field_name, $field_data, MigrationInterface
         'source' => $format_key,
       ],
     ];
-
-    $migration->setProcess($process);
+    $migration->mergeProcessOfProperty("$field_name/format", $process);
   }
 
   /**
@@ -168,8 +164,7 @@ protected function processTextField($field_name, $field_data, MigrationInterface
    *   The migration entity.
    */
   protected function processFileField($field_name, $field_data, MigrationInterface $migration) {
-    $process = $migration->getProcess();
-    $process[$field_name] = [
+    $process = [
       'plugin' => 'd6_cck_file',
       'source' => [
         $field_name,
@@ -177,7 +172,7 @@ protected function processFileField($field_name, $field_data, MigrationInterface
         $field_name . '_data',
       ],
     ];
-    $migration->setProcess($process);
+    $migration->mergeProcessOfProperty($field_name, $process);
   }
 
   /**
@@ -193,8 +188,7 @@ protected function processFileField($field_name, $field_data, MigrationInterface
   protected function processLinkField($field_name, $field_data, MigrationInterface $migration) {
     // Specifically process the link field until core is fixed.
     // @see https://www.drupal.org/node/2235457
-    $process = $migration->getProcess();
-    $process[$field_name] = [
+    $process = [
       'plugin' => 'd6_cck_link',
       'source' => [
         $field_name,
@@ -202,7 +196,7 @@ protected function processLinkField($field_name, $field_data, MigrationInterface
         $field_name . '_attributes',
       ],
     ];
-    $migration->setProcess($process);
+    $migration->mergeProcessOfProperty($field_name, $process);
   }
 
 }
