diff --git a/core/modules/entity/src/EntityDisplayBase.php b/core/modules/entity/src/EntityDisplayBase.php
index 34dc815..cc27fbd 100644
--- a/core/modules/entity/src/EntityDisplayBase.php
+++ b/core/modules/entity/src/EntityDisplayBase.php
@@ -313,6 +313,12 @@ public function setComponent($name, array $options = array()) {
       $options = $this->pluginManager->prepareConfiguration($field_definition->getType(), $options);
     }
 
+    if (isset($options['third_party_settings'])) {
+      foreach (array_keys($options['third_party_settings']) as $module) {
+        $this->addDependency('module', $module);
+      }
+    }
+
     $this->content[$name] = $options;
     unset($this->hidden[$name]);
     unset($this->plugins[$name]);
diff --git a/core/modules/field/tests/modules/field_test/field_test.module b/core/modules/field/tests/modules/field_test/field_test.module
index 45a0c0d..e5ad8ef 100644
--- a/core/modules/field/tests/modules/field_test/field_test.module
+++ b/core/modules/field/tests/modules/field_test/field_test.module
@@ -175,14 +175,16 @@ function field_test_field_widget_settings_summary_alter(&$summary, $context) {
 }
 
 /**
- * Implements hook_field_formatter_settings_form_alter().
+ * Implements hook_field_formatter_third_party_settings_form().
  */
-function field_test_field_formatter_settings_form_alter(&$element, &$form_state, $context) {
-  $element['field_test_formatter_settings_form_alter'] = array(
+function field_test_field_formatter_third_party_settings_form($plugin, \Drupal\Core\Field\FieldDefinitionInterface $field_definition, $view_mode, $form, $form_state) {
+  $third_party = $plugin->getSetting('third_party_settings');
+  $element['field_test_field_formatter_third_party_settings_form'] = array(
     '#type' => 'textfield',
-    '#title' => t('Formatter settings form alter'),
-    '#default_value' => $context['formatter']->getSetting('field_test_formatter_settings_form_alter'),
+    '#title' => t('3rd party formatter settings form'),
+    '#default_value' => $third_party['field_test'],
   );
+  return $element;
 }
 
 /**
diff --git a/core/modules/field_ui/field_ui.api.php b/core/modules/field_ui/field_ui.api.php
index 255ce85..93982a7 100644
--- a/core/modules/field_ui/field_ui.api.php
+++ b/core/modules/field_ui/field_ui.api.php
@@ -13,29 +13,34 @@
 /**
  * Alters the formatter settings form.
  *
- * @param $element
- *   Form array.
- * @param $form_state
- *   The form state of the (entire) configuration form.
- * @param $context
- *   An associative array with the following elements:
- *   - formatter: The formatter object.
- *   - field_definition: The field definition.
- *   - view_mode: The view mode being configured.
- *   - form: The (entire) configuration form array.
+ * @param object $plugin
+ *   The widget or formatter.
+ * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+ *   The field definition.
+ * @param $view_mode
+ *   The entity view or form mode.
+ * @param array $form
+ *   The The (entire) configuration form array.
+ * @param array $form_state
+ *   The form state.
+ *
+ *  @return array
+ *    Returns the form array to be built.
  *
  * @see \Drupal\field_ui\DisplayOverView.
  */
-function hook_field_formatter_settings_form_alter(&$element, &$form_state, $context) {
+function hook_field_formatter_third_party_settings_form($plugin, \Drupal\Core\Field\FieldDefinitionInterface $field_definition, $view_mode, $form, $form_state) {
   // Add a 'mysetting' checkbox to the settings form for 'foo_formatter'
   // field formatters.
-  if ($context['formatter']->getPluginId() == 'foo_formatter') {
-    $element['mysetting'] = array(
+  if ($plugin->getPluginId() == 'foo_formatter') {
+    $third_party = $plugin->getSetting('third_party_settings');
+    $element['my_setting'] = array(
       '#type' => 'checkbox',
       '#title' => t('My setting'),
-      '#default_value' => $context['formatter']->getSetting('mysetting'),
+      '#default_value' => $third_party['my_setting'],
     );
   }
+  return $element;
 }
 
 /**
diff --git a/core/modules/field_ui/src/DisplayOverview.php b/core/modules/field_ui/src/DisplayOverview.php
index 956d15f..149aed4 100644
--- a/core/modules/field_ui/src/DisplayOverview.php
+++ b/core/modules/field_ui/src/DisplayOverview.php
@@ -231,13 +231,18 @@ protected function getFieldLabelOptions() {
    * {@inheritdoc}
    */
   protected function alterSettingsForm(array &$settings_form, $plugin, FieldDefinitionInterface $field_definition, array $form, array &$form_state) {
-    $context = array(
-      'formatter' => $plugin,
-      'field_definition' => $field_definition,
-      'view_mode' => $this->mode,
-      'form' => $form,
-    );
-    $this->moduleHandler->alter('field_formatter_settings_form', $settings_form, $form_state, $context);
+    // Iterate through the modules calling their
+    // field_formatter_third_party_settings_form handlers (if any):
+    foreach ($this->moduleHandler->getImplementations('field_formatter_third_party_settings_form') as $module) {
+      // Index the settings form by module name.
+      $settings_form['third_party'][$module] = $this->moduleHandler->invoke($module, 'field_formatter_third_party_settings_form', array(
+        $plugin,
+        $field_definition,
+        $this->mode,
+        $form,
+        $form_state,
+      ));
+    }
   }
 
   /**
diff --git a/core/modules/field_ui/src/DisplayOverviewBase.php b/core/modules/field_ui/src/DisplayOverviewBase.php
index 2a6f46f..70e6cef 100644
--- a/core/modules/field_ui/src/DisplayOverviewBase.php
+++ b/core/modules/field_ui/src/DisplayOverviewBase.php
@@ -348,7 +348,9 @@ protected function buildFieldRow(FieldDefinitionInterface $field_definition, Ent
       if ($plugin) {
         // Generate the settings form and allow other modules to alter it.
         $settings_form = $plugin->settingsForm($form, $form_state);
-        $this->alterSettingsForm($settings_form, $plugin, $field_definition, $form, $form_state);
+        $additional_settings_form = array();
+        $this->alterSettingsForm($additional_settings_form, $plugin, $field_definition, $form, $form_state);
+        $settings_form += $additional_settings_form;
 
         if ($settings_form) {
           $field_row['plugin']['#cell_attributes'] = array('colspan' => 3);
@@ -524,6 +526,7 @@ public function submitForm(array &$form, array &$form_state) {
 
         // Only save settings actually used by the selected plugin.
         $default_settings = $this->pluginManager->getDefaultSettings($values['type']);
+        $third_party = !empty($settings['third_party']) ? $settings['third_party'] : array();
         $settings = array_intersect_key($settings, $default_settings);
 
         // Default component values.
@@ -533,6 +536,11 @@ public function submitForm(array &$form, array &$form_state) {
           'settings' => $settings
         );
 
+        // Add third party settings.
+        if (!empty($third_party)) {
+          $component_values['third_party_settings'] = $third_party;
+        }
+
         // Only formatters have configurable label visibility.
         if (isset($values['label'])) {
           $component_values['label'] = $values['label'];
diff --git a/core/modules/field_ui/src/FormDisplayOverview.php b/core/modules/field_ui/src/FormDisplayOverview.php
index 7c0a5ff..16f8bd4 100644
--- a/core/modules/field_ui/src/FormDisplayOverview.php
+++ b/core/modules/field_ui/src/FormDisplayOverview.php
@@ -190,6 +190,7 @@ protected function alterSettingsForm(array &$settings_form, $plugin, FieldDefini
       'form' => $form,
     );
     $this->moduleHandler->alter('field_widget_settings_form', $settings_form, $form_state, $context);
+    $settings_form = array('widget' => $settings_form);
   }
 
   /**
diff --git a/core/modules/field_ui/src/Tests/ManageDisplayTest.php b/core/modules/field_ui/src/Tests/ManageDisplayTest.php
index c98d52d..84daa6d 100644
--- a/core/modules/field_ui/src/Tests/ManageDisplayTest.php
+++ b/core/modules/field_ui/src/Tests/ManageDisplayTest.php
@@ -100,13 +100,13 @@ function testFormatterUI() {
     $this->drupalPostAjaxForm(NULL, array(), "field_test_settings_edit");
 
     // Assert that the field added in
-    // field_test_field_formatter_settings_form_alter() is present.
-    $fieldname = 'fields[field_test][settings_edit_form][settings][field_test_formatter_settings_form_alter]';
-    $this->assertField($fieldname, 'The field added in hook_field_formatter_settings_form_alter() is present on the settings form.');
+    // field_test_field_formatter_third_party_settings_form() is present.
+    $fieldname = 'fields[field_test][settings_edit_form][third_party][field_test][field_test_field_formatter_third_party_settings_form]';
+    $this->assertField($fieldname, 'The field added in hook_field_formatter_third_party_settings_form() is present on the settings form.');
     $edit = array($fieldname => 'foo');
     $this->drupalPostAjaxForm(NULL, $edit, "field_test_plugin_settings_update");
 
-    // Confirm that the extra settings are not updated on the settings form.
+    // Confirm that the third_party_settings settings are not updated on the settings form.
     $this->drupalPostAjaxForm(NULL, array(), "field_test_settings_edit");
     $this->assertFieldByName($fieldname, '');
 
@@ -194,12 +194,12 @@ public function testWidgetUI() {
 
     // Assert that the field added in
     // field_test_field_widget_settings_form_alter() is present.
-    $fieldname = 'fields[field_test][settings_edit_form][settings][field_test_widget_settings_form_alter]';
+    $fieldname = 'fields[field_test][settings_edit_form][settings][widget][field_test_widget_settings_form_alter]';
     $this->assertField($fieldname, 'The field added in hook_field_widget_settings_form_alter() is present on the settings form.');
     $edit = array($fieldname => 'foo');
     $this->drupalPostAjaxForm(NULL, $edit, "field_test_plugin_settings_update");
 
-    // Confirm that the extra settings are not updated on the settings form.
+    // Confirm that the third party settings are not updated on the settings form.
     $this->drupalPostAjaxForm(NULL, array(), "field_test_settings_edit");
     $this->assertFieldByName($fieldname, '');
   }
