diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml
index 3edb8057..7b658e0 100644
--- a/core/config/schema/core.data_types.schema.yml
+++ b/core/config/schema/core.data_types.schema.yml
@@ -650,12 +650,9 @@ field.field_settings.integer:
     max:
       type: integer
       label: 'Maximum'
-    prefix:
+    format_plural_string:
       type: label
-      label: 'Prefix'
-    suffix:
-      type: label
-      label: 'Suffix'
+      label: 'Plural formatted prefix/suffix'
 
 field.value.integer:
   type: mapping
@@ -688,12 +685,9 @@ field.field_settings.decimal:
     max:
       type: float
       label: 'Maximum'
-    prefix:
-      type: label
-      label: 'Prefix'
-    suffix:
+    format_plural_string:
       type: label
-      label: 'Suffix'
+      label: 'Plural formatted prefix/suffix'
 
 field.value.decimal:
    type: mapping
@@ -719,12 +713,9 @@ field.field_settings.float:
     max:
       type: float
       label: 'Maximum'
-    prefix:
-      type: label
-      label: 'Prefix'
-    suffix:
+    format_plural_string:
       type: label
-      label: 'Suffix'
+      label: 'Plural formatted prefix/suffix'
 
 field.value.float:
   type: mapping
diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml
index 71b7ccd..984056f 100644
--- a/core/config/schema/core.entity.schema.yml
+++ b/core/config/schema/core.entity.schema.yml
@@ -202,6 +202,9 @@ field.widget.settings.number:
     placeholder:
       type: label
       label: 'Placeholder'
+    format_plural:
+      type: boolean
+      label: 'Whether or not to display prefix/suffix'
 
 field.widget.settings.checkbox:
   type: mapping
@@ -292,9 +295,12 @@ field.formatter.settings.number_decimal:
     scale:
       type: integer
       label: 'Scale'
-    prefix_suffix:
-      type: boolean
-      label: 'Display prefix and suffix.'
+    format_plural:
+      type: string
+      label: 'Which prefix/suffix to display, if any'
+    format_plural_string:
+      type: label
+      label: 'Override for prefix/suffix'
 
 field.formatter.settings.number_integer:
   type: mapping
@@ -303,9 +309,12 @@ field.formatter.settings.number_integer:
     thousand_separator:
       type: string
       label: 'Thousand marker'
-    prefix_suffix:
-      type: boolean
-      label: 'Display prefix and suffix.'
+    format_plural:
+      type: string
+      label: 'Which prefix/suffix to display, if any'
+    format_plural_string:
+      type: label
+      label: 'Override for prefix/suffix'
 
 field.formatter.settings.number_unformatted:
   type: mapping
diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php b/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php
index bee0144..9760f29 100644
--- a/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php
+++ b/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php
@@ -141,6 +141,11 @@ public function getRenderer($field_name) {
 
     // Instantiate the widget object from the stored display properties.
     if (($configuration = $this->getComponent($field_name)) && isset($configuration['type']) && ($definition = $this->getFieldDefinition($field_name))) {
+      // Pass the language of the display configuration down to the widget,
+      // which otherwise doesn't have access to it because it is not a
+      // stand-alone config entity. It may be relevant for some operations,
+      // such as using plural formatting as a field prefix.
+      $configuration['settings']['_settings_langcode'] = $this->langcode;
       $widget = $this->pluginManager->getInstance(array(
         'field_definition' => $definition,
         'form_mode' => $this->originalMode,
diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
index 27884cd..f7d1f3c 100644
--- a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
+++ b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
@@ -197,6 +197,11 @@ public function getRenderer($field_name) {
 
     // Instantiate the formatter object from the stored display properties.
     if (($configuration = $this->getComponent($field_name)) && isset($configuration['type']) && ($definition = $this->getFieldDefinition($field_name))) {
+      // Pass the language of the display configuration down to the formatter,
+      // which otherwise doesn't have access to it because it is not a
+      // stand-alone config entity. It may be relevant for some operations,
+      // such as plural formatting.
+      $configuration['settings']['_settings_langcode'] = $this->langcode;
       $formatter = $this->pluginManager->getInstance(array(
         'field_definition' => $definition,
         'view_mode' => $this->originalMode,
diff --git a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
index b835327..5b374b8 100644
--- a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
+++ b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
@@ -292,6 +292,11 @@ public function toArray() {
       if (!$definition->isDisplayConfigurable($this->displayContext)) {
         unset($properties['content'][$field_name]);
         unset($properties['hidden'][$field_name]);
+        // If _settings_langcode is in the settings, remove it. It should never
+        // be saved in the configuration.
+        if (isset($properties['content'][$field_name]['settings']['_settings_langcode'])) {
+          unset($properties['content'][$field_name]['settings']['_settings_langcode']);
+        }
       }
     }
 
@@ -339,6 +344,12 @@ public function setComponent($name, array $options = array()) {
     // Ensure we always have an empty settings and array.
     $options += ['settings' => [], 'third_party_settings' => []];
 
+    // If _settings_langcode is in the settings, remove it. It should never
+    // be saved in the configuration.
+    if (isset($options['settings']['_settings_langcode'])) {
+      unset($options['settings']['_settings_langcode']);
+    }
+
     $this->content[$name] = $options;
     unset($this->hidden[$name]);
     unset($this->plugins[$name]);
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index d212474..12091df 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -13,6 +13,7 @@
 use Drupal\Core\Field\FieldItemInterface;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
+use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\TypedData\TranslatableInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -453,10 +454,21 @@ protected function getSingleFieldDisplay($entity, $field_name, $display_options)
       $bundle = $entity->bundle();
       $key = $entity_type_id . ':' . $bundle . ':' . $field_name . ':' . hash('crc32b', serialize($display_options));
       if (!isset($this->singleFieldDisplays[$key])) {
+        // Assign the incoming '_settings_langcode' as the langcode of the
+        // EntityViewDisplay, or default to the current interface language.
+        if (isset($display_options['settings']['_settings_langcode'])) {
+          $langcode = $display_options['settings']['_settings_langcode'];
+          unset($display_options['settings']['_settings_langcode']);
+        }
+        else {
+          $langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_INTERFACE)->getId();
+        }
+
         $this->singleFieldDisplays[$key] = EntityViewDisplay::create(array(
           'targetEntityType' => $entity_type_id,
           'bundle' => $bundle,
           'status' => TRUE,
+          'langcode' => $langcode,
         ))->setComponent($field_name, $display_options);
       }
       $display = $this->singleFieldDisplays[$key];
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php b/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php
index eff6516..42f8248 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php
@@ -118,7 +118,11 @@ public function resetCache(array $entities = NULL);
    *       'default_formatter' for the field type. The default formatter will
    *       also be used if the requested formatter is not available.
    *     - settings: (array) Settings specific to the formatter. Defaults to the
-   *       formatter's default settings.
+   *       formatter's default settings. A '_settings_langcode' entry should be
+   *       present to indicate the language of the settings that are being
+   *       provided (typically, the language of the configuration entity that
+   *       contains the formatter, such as an entity view mode). If absent, the
+   *       current interface language will be assumed.
    *     - weight: (float) The weight to assign to the renderable element.
    *       Defaults to 0.
    *
diff --git a/core/lib/Drupal/Core/Field/FormatterPluginManager.php b/core/lib/Drupal/Core/Field/FormatterPluginManager.php
index e6054a9..9136c13 100644
--- a/core/lib/Drupal/Core/Field/FormatterPluginManager.php
+++ b/core/lib/Drupal/Core/Field/FormatterPluginManager.php
@@ -73,7 +73,7 @@ public function createInstance($plugin_id, array $configuration = array()) {
   }
 
   /**
-   * Overrides PluginManagerBase::getInstance().
+   * Creates a formatter instance with the provided options.
    *
    * @param array $options
    *   An array with the following key/value pairs:
@@ -92,6 +92,11 @@ public function createInstance($plugin_id, array $configuration = array()) {
    *       also be used if the requested formatter is not available.
    *     - settings: (array) Settings specific to the formatter. Each setting
    *       defaults to the default value specified in the formatter definition.
+   *       A '_settings_langcode' entry should be present to indicate the
+   *       language of the settings that are being provided (typically, the
+   *       language of the configuration entity that contains the formatter,
+   *       such as an entity view mode). If absent, the current interface
+   *       language will be assumed.
    *     - third_party_settings: (array) Settings provided by other extensions
    *       through hook_field_formatter_third_party_settings_form().
    *
@@ -116,7 +121,7 @@ public function getInstance(array $options) {
     // - the formatter is not applicable to the field definition.
     $definition = $this->getDefinition($configuration['type'], FALSE);
     if (!isset($definition['class']) || !in_array($field_type, $definition['field_types']) || !$definition['class']::isApplicable($field_definition)) {
-      // Grab the default widget for the field type.
+      // Grab the default formatter for the field type.
       $field_type_definition = $this->fieldTypeManager->getDefinition($field_type);
       if (empty($field_type_definition['default_formatter'])) {
         return NULL;
@@ -128,6 +133,7 @@ public function getInstance(array $options) {
       'field_definition' => $field_definition,
       'view_mode' => $options['view_mode'],
     );
+
     return $this->createInstance($plugin_id, $configuration);
   }
 
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/DecimalFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/DecimalFormatter.php
index 0e43ac1..7c9a17b 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/DecimalFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/DecimalFormatter.php
@@ -32,10 +32,8 @@ class DecimalFormatter extends NumericFormatterBase {
    */
   public static function defaultSettings() {
     return array(
-      'thousand_separator' => '',
       'decimal_separator' => '.',
       'scale' => 2,
-      'prefix_suffix' => TRUE,
     ) + parent::defaultSettings();
   }
 
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/IntegerFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/IntegerFormatter.php
index 8768474..20e5d4b 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/IntegerFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/IntegerFormatter.php
@@ -27,16 +27,6 @@ class IntegerFormatter extends NumericFormatterBase {
   /**
    * {@inheritdoc}
    */
-  public static function defaultSettings() {
-    return array(
-      'thousand_separator' => '',
-      'prefix_suffix' => TRUE,
-    ) + parent::defaultSettings();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   protected function numberFormat($number) {
     return number_format($number, 0, '', $this->getSetting('thousand_separator'));
   }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php
index 28b0159..a9510d9 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Field\FormatterBase;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
 
 /**
  * Parent plugin for decimal and integer formatters.
@@ -20,6 +21,32 @@
   use AllowedTagsXssTrait;
 
   /**
+   * Indicates plural formatting using the setting from the field.
+   */
+  const FORMAT_PLURAL_USE_FIELD_SETTING = 'field';
+
+  /**
+   * Indicates plural formatting using the setting from the formatter.
+   */
+  const FORMAT_PLURAL_USE_FORMATTER_SETTING = 'formatter';
+
+  /**
+   * Indicates no plural formatting.
+   */
+  const FORMAT_PLURAL_NONE = 'none';
+
+   /**
+    * {@inheritdoc}
+    */
+  public static function defaultSettings() {
+    return array(
+      'thousand_separator' => '',
+      'format_plural' => NumericFormatterBase::FORMAT_PLURAL_NONE,
+      'format_plural_string' => '',
+    ) + parent::defaultSettings();
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function settingsForm(array $form, FormStateInterface $form_state) {
@@ -39,16 +66,82 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
       '#weight' => 0,
     );
 
-    $elements['prefix_suffix'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Display prefix and suffix'),
-      '#default_value' => $this->getSetting('prefix_suffix'),
-      '#weight' => 10,
+    $elements['format_plural'] = array(
+      '#type' => 'radios',
+      '#title' => $this->t('Display prefix/suffix'),
+      '#default_value' => $this->getSetting('format_plural'),
+      '#options' => array(
+        NumericFormatterBase::FORMAT_PLURAL_NONE => $this->t('No prefix/suffix'),
+        NumericFormatterBase::FORMAT_PLURAL_USE_FIELD_SETTING => $this->t('Use setting from the field settings'),
+        NumericFormatterBase::FORMAT_PLURAL_USE_FORMATTER_SETTING => $this->t('Override the setting from the field settings'),
+      ),
+    );
+
+    // @todo This field needs to have some kind of #states magic so that it
+    // only shows if the option on format_plural is
+    // NumericFormatterBase::FORMAT_PLURAL_USE_FORMATTER_SETTING.
+    // Need to do this before this patch is finalized!
+    $elements['format_plural_values'] = array(
+      '#type' => 'fieldset',
+      '#title' => $this->t('Prefix/suffix override'),
+      '#after_build' => [[get_class($this), 'formatPluralValuesAfterBuild']],
     );
 
+    $langcode = $this->getSetting('_settings_langcode');
+    $plurals = $this->getNumberOfPlurals($langcode);
+    $labels = $this->getPluralLabels($langcode);
+    $plural_string = $this->getSetting('format_plural_string');
+    if (!$plural_string) {
+      $settings = $this->getFieldSettings();
+      if (isset($settings['format_plural_string'])) {
+        $plural_string = $settings['format_plural_string'];
+      }
+    }
+    $plural_array = explode(LOCALE_PLURAL_DELIMITER, $plural_string);
+    for ($i = 0; $i < $plurals; $i++) {
+      $elements['format_plural_values'][$i] = array(
+        '#type' => 'textfield',
+        '#title' => $labels[$i]['label'],
+        '#description' => $labels[$i]['description'],
+        '#default_value' => isset($plural_array[$i]) ? $plural_array[$i] : '',
+      );
+    }
+
     return $elements;
   }
 
+ /**
+   * After-build callback: Sets the value for the format_plural_string property.
+   *
+   * This method is assigned as an #after_build function in the settings form.
+   *
+   * The user interface for setting up singular/plural forms is an array of text
+   * fields, for usability, but for translation purposes, the values have to be
+   * stored as a single string in the field settings. This function implodes the
+   * values.
+   *
+   * @param array $element
+   *   Textfield element where the plural format should be set.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   *
+   * @return array
+   *   Textfield element with plural string set.
+   */
+  public static function formatPluralValuesAfterBuild($element, FormStateInterface $form_state) {
+    if ($form_state->isProcessingInput()) {
+      $keys = $element['#parents'];
+      $array_value = $form_state->getValue($keys);
+      $form_state->unsetValue($keys);
+      $string_value = implode(LOCALE_PLURAL_DELIMITER, $array_value);
+      array_pop($keys);
+      $keys[] = 'format_plural_string';
+      $form_state->setValue($keys, $string_value);
+
+    }
+    return $element;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -56,8 +149,11 @@ public function settingsSummary() {
     $summary = array();
 
     $summary[] = $this->numberFormat(1234.1234567890);
-    if ($this->getSetting('prefix_suffix')) {
-      $summary[] = t('Display with prefix and suffix.');
+    if ($this->getSetting('format_plural') == NumericFormatterBase::FORMAT_PLURAL_USE_FIELD_SETTING) {
+      $summary[] = $this->t('Display prefix/suffix from the field settings.');
+    }
+    elseif ($this->getSetting('format_plural') == NumericFormatterBase::FORMAT_PLURAL_USE_FORMATTER_SETTING) {
+      $summary[] = $this->t('Display overridden prefix/suffix.');
     }
 
     return $summary;
@@ -68,19 +164,24 @@ public function settingsSummary() {
    */
   public function viewElements(FieldItemListInterface $items, $langcode) {
     $elements = array();
-    $settings = $this->getFieldSettings();
+    $field_settings = $this->getFieldSettings();
 
     foreach ($items as $delta => $item) {
       $output = $this->numberFormat($item->value);
 
       // Account for prefix and suffix.
-      if ($this->getSetting('prefix_suffix')) {
-        $prefixes = isset($settings['prefix']) ? array_map(array('Drupal\Core\Field\FieldFilteredMarkup', 'create'), explode('|', $settings['prefix'])) : array('');
-        $suffixes = isset($settings['suffix']) ? array_map(array('Drupal\Core\Field\FieldFilteredMarkup', 'create'), explode('|', $settings['suffix'])) : array('');
-        $prefix = (count($prefixes) > 1) ? $this->formatPlural($item->value, $prefixes[0], $prefixes[1]) : $prefixes[0];
-        $suffix = (count($suffixes) > 1) ? $this->formatPlural($item->value, $suffixes[0], $suffixes[1]) : $suffixes[0];
-        $output = $prefix . $output . $suffix;
+      $format_string = '';
+      if ($this->getSetting('format_plural') == NumericFormatterBase::FORMAT_PLURAL_USE_FIELD_SETTING) {
+        $format_string = $field_settings['format_plural_string'];
+      }
+      elseif ($this->getSetting('format_plural') == NumericFormatterBase::FORMAT_PLURAL_USE_FORMATTER_SETTING) {
+        $format_string = $this->getSetting('format_plural_string');
       }
+
+      if ($format_string) {
+        $output = PluralTranslatableMarkup::createFromTranslatedString($item->value, $format_string, ['@count' => $output], ['langcode' => $this->getSetting('_settings_langcode')]);
+      }
+
       // Output the raw value in a content attribute if the text of the HTML
       // element differs from the raw value (for example when a prefix is used).
       if (isset($item->_attributes) && $item->value != $output) {
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
index 78d5d9e..2c3377a 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
@@ -40,18 +40,6 @@ public static function defaultStorageSettings() {
   /**
    * {@inheritdoc}
    */
-  public static function defaultFieldSettings() {
-    return array(
-      'min' => '',
-      'max' => '',
-      'prefix' => '',
-      'suffix' => '',
-    ) + parent::defaultFieldSettings();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('integer')
       ->setLabel(t('Integer value'))
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/NumericItemBase.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/NumericItemBase.php
index 9f9bd0b..b51e96c 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/NumericItemBase.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/NumericItemBase.php
@@ -22,8 +22,7 @@ public static function defaultFieldSettings() {
     return array(
       'min' => '',
       'max' => '',
-      'prefix' => '',
-      'suffix' => '',
+      'format_plural_string' => '',
     ) + parent::defaultFieldSettings();
   }
 
@@ -36,31 +35,66 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
 
     $element['min'] = array(
       '#type' => 'number',
-      '#title' => t('Minimum'),
+      '#title' => $this->t('Minimum'),
       '#default_value' => $settings['min'],
-      '#description' => t('The minimum value that should be allowed in this field. Leave blank for no minimum.'),
+      '#description' => $this->t('The minimum value that should be allowed in this field. Leave blank for no minimum.'),
     );
     $element['max'] = array(
       '#type' => 'number',
-      '#title' => t('Maximum'),
+      '#title' => $this->t('Maximum'),
       '#default_value' => $settings['max'],
-      '#description' => t('The maximum value that should be allowed in this field. Leave blank for no maximum.'),
+      '#description' => $this->t('The maximum value that should be allowed in this field. Leave blank for no maximum.'),
     );
-    $element['prefix'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Prefix'),
-      '#default_value' => $settings['prefix'],
-      '#size' => 60,
-      '#description' => t("Define a string that should be prefixed to the value, like '$ ' or '&euro; '. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
-    );
-    $element['suffix'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Suffix'),
-      '#default_value' => $settings['suffix'],
-      '#size' => 60,
-      '#description' => t("Define a string that should be suffixed to the value, like ' m', ' kb/s'. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
+
+    $element['format_plural_values'] = array(
+      '#type' => 'fieldset',
+      '#title' => $this->t('Plural formatted prefix/suffix'),
+      '#after_build' => [[get_class($this), 'formatPluralValuesAfterBuild']],
     );
+    $langcode = $this->getFieldDefinition()->get('langcode');
+    $plurals = $this->getNumberOfPlurals($langcode);
+    $labels = $this->getPluralLabels($langcode);
+    $plural_array = explode(LOCALE_PLURAL_DELIMITER, $settings['format_plural_string']);
+    for ($i = 0; $i < $plurals; $i++) {
+      $element['format_plural_values'][$i] = array(
+        '#type' => 'textfield',
+        '#title' => $labels[$i]['label'],
+        '#description' => $labels[$i]['description'],
+        '#default_value' => isset($plural_array[$i]) ? $plural_array[$i] : '',
+      );
+    }
+
+    return $element;
+  }
 
+ /**
+   * After-build callback: Sets the value for the format_plural_string property.
+   *
+   * This method is assigned as an #after_build function in the settings form.
+   *
+   * The user interface for setting up singular/plural forms is an array of text
+   * fields, for usability, but for translation purposes, the values have to be
+   * stored as a single string in the field settings. This function implodes the
+   * values.
+   *
+   * @param array $element
+   *   Textfield element where the plural format should be set.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   *
+   * @return array
+   *   Textfield element with plural string set.
+   */
+  public static function formatPluralValuesAfterBuild($element, FormStateInterface $form_state) {
+    if ($form_state->isProcessingInput()) {
+      $keys = $element['#parents'];
+      $array_value = $form_state->getValue($keys);
+      $form_state->unsetValue($keys);
+      $string_value = implode(LOCALE_PLURAL_DELIMITER, $array_value);
+      array_pop($keys);
+      $keys[] = 'format_plural_string';
+      $form_state->setValue($keys, $string_value);
+    }
     return $element;
   }
 
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/NumberWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/NumberWidget.php
index 57abc60..f7f6420 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/NumberWidget.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/NumberWidget.php
@@ -34,6 +34,7 @@ class NumberWidget extends WidgetBase {
   public static function defaultSettings() {
     return array(
       'placeholder' => '',
+      'format_plural' => TRUE,
     ) + parent::defaultSettings();
   }
 
@@ -47,6 +48,14 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
       '#default_value' => $this->getSetting('placeholder'),
       '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
     );
+
+    $element['format_plural'] = array(
+      '#type' => 'checkbox',
+      '#title' => $this->t('Display prefix/suffix'),
+      '#description' => $this->t('If checked, prefix/suffix from the field will be displayed.'),
+      '#default_value' => $this->getSetting('format_plural'),
+    );
+
     return $element;
   }
 
@@ -58,10 +67,14 @@ public function settingsSummary() {
 
     $placeholder = $this->getSetting('placeholder');
     if (!empty($placeholder)) {
-      $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
+      $summary[] = $this->t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
     }
     else {
-      $summary[] = t('No placeholder');
+      $summary[] = $this->t('No placeholder');
+    }
+
+    if ($this->getSetting('format_plural')) {
+      $summary[] = $this->t('Prefix/suffix from the field are displayed');
     }
 
     return $summary;
@@ -100,13 +113,19 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     }
 
     // Add prefix and suffix.
-    if ($field_settings['prefix']) {
-      $prefixes = explode('|', $field_settings['prefix']);
-      $element['#field_prefix'] = FieldFilteredMarkup::create(array_pop($prefixes));
-    }
-    if ($field_settings['suffix']) {
-      $suffixes = explode('|', $field_settings['suffix']);
-      $element['#field_suffix'] = FieldFilteredMarkup::create(array_pop($suffixes));
+    if ($field_settings['format_plural_string'] && $this->getSetting('format_plural')) {
+      // The field setting is a string containing all plural variants, suitable
+      // for use in formatPlural() methods, but already translated into the
+      // UI language. Pop off the last plural variant, and use the parts
+      // before/after @count in that string as the prefix/suffix for this field.
+      $values = explode(LOCALE_PLURAL_DELIMITER, $field_settings['format_plural_string']);
+      $labels = explode('@count', array_pop($values));
+      if (isset($labels[0])) {
+        $element['#field_prefix'] = FieldFilteredMarkup::create(trim($labels[0]));
+      }
+      if (isset($labels[1])) {
+        $element['#field_suffix'] = FieldFilteredMarkup::create(trim($labels[1]));
+      }
     }
 
     return array('value' => $element);
diff --git a/core/lib/Drupal/Core/Field/WidgetPluginManager.php b/core/lib/Drupal/Core/Field/WidgetPluginManager.php
index 2bc41f1..510c685 100644
--- a/core/lib/Drupal/Core/Field/WidgetPluginManager.php
+++ b/core/lib/Drupal/Core/Field/WidgetPluginManager.php
@@ -55,7 +55,7 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
   }
 
   /**
-   * Overrides PluginManagerBase::getInstance().
+   * Creates a widget instance with the provided options.
    *
    * @param array $options
    *   An array with the following key/value pairs:
@@ -71,6 +71,11 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
    *       used if the requested widget is not available.
    *     - settings: (array) Settings specific to the widget. Each setting
    *       defaults to the default value specified in the widget definition.
+   *       A '_settings_langcode' entry should be present to indicate the
+   *       language of the settings that are being provided (typically, the
+   *       language of the configuration entity that contains the widget,
+   *       such as an entity form mode). If absent, the current interface
+   *       language will be assumed.
    *     - third_party_settings: (array) Settings provided by other extensions
    *       through hook_field_formatter_third_party_settings_form().
    *
diff --git a/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php b/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php
index 583ab18..4bcccd2 100644
--- a/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php
+++ b/core/lib/Drupal/Core/StringTranslation/PluralTranslatableMarkup.php
@@ -63,7 +63,9 @@ class PluralTranslatableMarkup extends TranslatableMarkup {
    *   See \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for
    *   additional information about placeholders. Note that you do not need to
    *   include @count in this array; this replacement is done automatically
-   *   for the plural cases.
+   *   for the plural cases. But you can include @count to override the
+   *   replacement value (for instance, to use a formatted number instead of
+   *   the raw number).
    * @param array $options
    *   (optional) An associative array of additional options. See t() for
    *   allowed keys.
@@ -95,7 +97,9 @@ public function __construct($count, $singular, $plural, array $args = [], array
    *   Based on the first character of the key, the value is escaped and/or
    *   themed. See \Drupal\Component\Utility\SafeMarkup::format(). Note that you
    *   do not need to include @count in this array; this replacement is done
-   *   automatically for the plural cases.
+   *   automatically for the plural cases. But you can include @count to
+   *   override the replacement value (for instance, to use a formatted number
+   *   instead of the raw number).
    * @param array $options
    *   An associative array of additional options. See t() for allowed keys.
    *
@@ -123,7 +127,10 @@ public function render() {
     }
 
     $arguments = $this->getArguments();
-    $arguments['@count'] = $this->count;
+    // Allow overrides of what gets substituted in for @count.
+    if (!isset($arguments['@count'])) {
+      $arguments['@count'] = $this->count;
+    }
     $translated_array = explode(static::DELIMITER, $this->translatedString);
 
     if ($this->count == 1) {
diff --git a/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php b/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php
index f4b4bd3..cfe8167 100644
--- a/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php
+++ b/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php
@@ -84,6 +84,59 @@ protected function getNumberOfPlurals($langcode = NULL) {
   }
 
   /**
+   * Returns the labels and descriptions for plural variants in a language.
+   *
+   * @param string $langcode
+   *   The language code.
+   *
+   * @return array[]
+   *  An array of labels and descriptions to use in forms for the plural
+   *  variants of $langcode, translated into the current interface language.
+   *  Each item in the returned array is an array with elements 'label' and
+   *  'description' for the corresponding plural variant.
+   */
+  protected function getPluralLabels($langcode) {
+    $plurals = $this->getNumberOfPlurals($langcode);
+
+    // @todo The return values for both cases should be more relevant to the
+    // actual plural rules of the language; see
+    // https://www.drupal.org/node/2499639.
+
+    if ($plurals == 1) {
+      return [
+        [
+          'label' => $this->t('Form for all numbers'),
+          'description' => $this->t('Text to use for all numbers; @count will be replaced with the value.'),
+        ],
+      ];
+    }
+
+    if ($plurals == 2) {
+      return [
+        [
+          'label' => $this->t('Singular form'),
+          'description' => $this->t('Text to use for the singular form; @count will be replaced with the value.'),
+        ],
+        [
+          'label' => $this->t('Plural form'),
+          'description' => $this->t('Text to use for the plural form; @count will be replaced with the value.'),
+        ],
+      ];
+    }
+
+    // For the != 2 case, generate labels.
+    $labels = [];
+    for ($i = 0; $i < $plurals; $i++) {
+      $labels[] = [
+        'label' => ($i == 0 ? $this->t('Singular form') : $this->formatPlural($i, 'First plural form', '@count. plural form')),
+        'description' => $this->t('Text to use for this variant; @count will be replaced with the value.'),
+      ];
+    }
+
+    return $labels;
+  }
+
+  /**
    * Gets the string translation service.
    *
    * @return \Drupal\Core\StringTranslation\TranslationInterface
diff --git a/core/modules/field/src/Tests/Migrate/d6/MigrateFieldFormatterSettingsTest.php b/core/modules/field/src/Tests/Migrate/d6/MigrateFieldFormatterSettingsTest.php
index 1ad3d36..703e66b 100644
--- a/core/modules/field/src/Tests/Migrate/d6/MigrateFieldFormatterSettingsTest.php
+++ b/core/modules/field/src/Tests/Migrate/d6/MigrateFieldFormatterSettingsTest.php
@@ -73,7 +73,8 @@ public function testEntityDisplaySettings() {
     $expected['type'] = 'number_integer';
     $expected['settings'] = array(
       'thousand_separator' => ',',
-      'prefix_suffix' => TRUE,
+      'format_plural' => 'none',
+      'format_plural_string' => '',
     );
     $component = $display->getComponent('field_test_two');
     $this->assertIdentical($expected, $component);
@@ -83,7 +84,8 @@ public function testEntityDisplaySettings() {
        'scale' => 2,
        'decimal_separator' => '.',
        'thousand_separator' => ',',
-       'prefix_suffix' => TRUE,
+       'format_plural' => 'none',
+       'format_plural_string' => '',
     );
     $component = $display->getComponent('field_test_three');
     $this->assertIdentical($expected, $component);
diff --git a/core/modules/field/src/Tests/Migrate/d6/MigrateFieldInstanceTest.php b/core/modules/field/src/Tests/Migrate/d6/MigrateFieldInstanceTest.php
index c3c0cb6..e3f115c 100644
--- a/core/modules/field/src/Tests/Migrate/d6/MigrateFieldInstanceTest.php
+++ b/core/modules/field/src/Tests/Migrate/d6/MigrateFieldInstanceTest.php
@@ -39,8 +39,7 @@ public function testFieldInstanceMigration() {
     $expected = array(
       'min' => 10,
       'max' => 100,
-      'prefix' => 'pref',
-      'suffix' => 'suf',
+      'format_plural_string' => 'pref@count suf',
       'unsigned' => FALSE,
       'size' => 'normal',
     );
@@ -51,8 +50,7 @@ public function testFieldInstanceMigration() {
     $expected = array(
       'min' => 100.0,
       'max' => 200.0,
-      'prefix' => 'id-',
-      'suffix' => '',
+      'format_plural_string' => 'id-@count';
     );
     $this->assertIdentical($expected, $field->getSettings());
 
diff --git a/core/modules/field/src/Tests/Migrate/d6/MigrateFieldWidgetSettingsTest.php b/core/modules/field/src/Tests/Migrate/d6/MigrateFieldWidgetSettingsTest.php
index 891eb69..2244d1f 100644
--- a/core/modules/field/src/Tests/Migrate/d6/MigrateFieldWidgetSettingsTest.php
+++ b/core/modules/field/src/Tests/Migrate/d6/MigrateFieldWidgetSettingsTest.php
@@ -44,7 +44,7 @@ public function testWidgetSettings() {
     $component = $form_display->getComponent('field_test_two');
     $expected['type'] = 'number';
     $expected['weight'] = 1;
-    $expected['settings'] = array('placeholder' => '');
+    $expected['settings'] = array('placeholder' => '', 'format_plural' => TRUE);
     $this->assertIdentical($expected, $component);
 
     // Float field.
@@ -56,6 +56,7 @@ public function testWidgetSettings() {
     $component = $form_display->getComponent('field_test_email');
     $expected['type'] = 'email_default';
     $expected['weight'] = 6;
+    $expected['settings'] = array('placeholder' => '');
     $this->assertIdentical($expected, $component);
 
     // Link field.
diff --git a/core/modules/field/src/Tests/Number/NumberFieldTest.php b/core/modules/field/src/Tests/Number/NumberFieldTest.php
index f80dfab..64f746f 100644
--- a/core/modules/field/src/Tests/Number/NumberFieldTest.php
+++ b/core/modules/field/src/Tests/Number/NumberFieldTest.php
@@ -145,7 +145,7 @@ function testNumberIntegerField() {
       'entity_type' => 'entity_test',
       'bundle' => 'entity_test',
       'settings' => array(
-        'min' => $minimum, 'max' => $maximum, 'prefix' => 'ThePrefix',
+        'min' => $minimum, 'max' => $maximum, 'format_plural_string' => 'ThePrefix@count',
       )
     ))->save();
 
@@ -161,7 +161,7 @@ function testNumberIntegerField() {
       ->setComponent($field_name, array(
         'type' => 'number_integer',
         'settings' => array(
-          'prefix_suffix' => FALSE,
+          'format_plural' => 'none',
         ),
       ))
       ->save();
@@ -248,12 +248,13 @@ function testNumberIntegerField() {
       $this->assertNoFieldByXpath('//div[@content="' . $valid_entry . '"]', NULL, 'The "content" attribute is not present since the Prefix is not being displayed');
     }
 
-    // Test for the content attribute when a Prefix is displayed. Presumably this also tests for the attribute when a Suffix is displayed.
+    // Test for the content attribute using the field setting for plural
+    // prefix/suffix formatting.
     entity_get_display('entity_test', 'entity_test', 'default')
       ->setComponent($field_name, array(
         'type' => 'number_integer',
         'settings' => array(
-          'prefix_suffix' => TRUE,
+          'format_plural' => 'field',
         ),
       ))
       ->save();
@@ -268,6 +269,20 @@ function testNumberIntegerField() {
     $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
     $this->drupalGet('entity_test/' . $id);
     $this->assertFieldByXPath('//div[@content="' . $integer_value . '"]', 'ThePrefix' . $integer_value, 'The "content" attribute has been set to the value of the field, and the prefix is being displayed.');
+
+    // Change to using an overridden plural formatting string.
+    entity_get_display('entity_test', 'entity_test', 'default')
+      ->setComponent($field_name, array(
+        'type' => 'number_integer',
+        'settings' => array(
+          'format_plural' => 'formatter',
+          'format_plural_string' => 'NewPrefix@count',
+        ),
+      ))
+      ->save();
+    $this->drupalGet('entity_test/' . $id);
+    $this->assertFieldByXPath('//div[@content="' . $integer_value . '"]', 'NewPrefix' . $integer_value, 'The "content" attribute has been set to the value of the field, and the overridden prefix is being displayed.');
+
   }
 
   /**
@@ -394,8 +409,7 @@ function testNumberFormatter() {
       'entity_type' => 'node',
       'bundle' => $type,
       'settings' => array(
-        'prefix' => $prefix,
-        'suffix' => $suffix
+        'format_plural_string' => $prefix . '@count' . $suffix;
       ),
     ))->save();
 
@@ -404,8 +418,7 @@ function testNumberFormatter() {
       'entity_type' => 'node',
       'bundle' => $type,
       'settings' => array(
-        'prefix' => $prefix,
-        'suffix' => $suffix
+        'format_plural_string' => $prefix . '@count' . $suffix;
       ),
     ))->save();
 
@@ -456,7 +469,7 @@ function testNumberFormatter() {
 
     $this->drupalPostAjaxForm(NULL, array(), "${float_field}_settings_edit");
     $edit = array(
-      "fields[${float_field}][settings_edit_form][settings][prefix_suffix]" => TRUE,
+      "fields[${float_field}][settings_edit_form][settings][format_plural]" => 'field',
       "fields[${float_field}][settings_edit_form][settings][scale]" => $scale,
       "fields[${float_field}][settings_edit_form][settings][decimal_separator]" => $decimal_separator,
       "fields[${float_field}][settings_edit_form][settings][thousand_separator]" => $thousand_separator,
@@ -482,7 +495,7 @@ function testNumberFormatter() {
 
     $this->drupalPostAjaxForm(NULL, array(), "${integer_field}_settings_edit");
     $edit = array(
-      "fields[${integer_field}][settings_edit_form][settings][prefix_suffix]" => FALSE,
+      "fields[${integer_field}][settings_edit_form][settings][format_plural]" => 'none',
       "fields[${integer_field}][settings_edit_form][settings][thousand_separator]" => $thousand_separator,
     );
     $this->drupalPostAjaxForm(NULL, $edit, "${integer_field}_plugin_settings_update");
diff --git a/core/modules/field_ui/src/Tests/EntityDisplayTest.php b/core/modules/field_ui/src/Tests/EntityDisplayTest.php
index 7c7a48b..d9cd658 100644
--- a/core/modules/field_ui/src/Tests/EntityDisplayTest.php
+++ b/core/modules/field_ui/src/Tests/EntityDisplayTest.php
@@ -220,6 +220,7 @@ public function testFieldComponent() {
     // Check that the getFormatter() method returns the correct formatter plugin.
     $formatter = $display->getRenderer($field_name);
     $this->assertEqual($formatter->getPluginId(), $default_formatter);
+    $formatter_settings['_settings_langcode'] = 'en';
     $this->assertEqual($formatter->getSettings(), $formatter_settings);
 
     // Check that the formatter is statically persisted, by assigning an
diff --git a/core/modules/field_ui/src/Tests/EntityFormDisplayTest.php b/core/modules/field_ui/src/Tests/EntityFormDisplayTest.php
index b002106..6138b7c 100644
--- a/core/modules/field_ui/src/Tests/EntityFormDisplayTest.php
+++ b/core/modules/field_ui/src/Tests/EntityFormDisplayTest.php
@@ -91,6 +91,7 @@ public function testFieldComponent() {
     // Check that the getWidget() method returns the correct widget plugin.
     $widget = $form_display->getRenderer($field_name);
     $this->assertEqual($widget->getPluginId(), $default_widget);
+    $widget_settings['_settings_langcode'] = 'en';
     $this->assertEqual($widget->getSettings(), $widget_settings);
 
     // Check that the widget is statically persisted, by assigning an
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_nid_argument.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_nid_argument.yml
index b61f1ad..c6b5b1c 100644
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_nid_argument.yml
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_nid_argument.yml
@@ -106,7 +106,7 @@ display:
           type: number_integer
           settings:
             thousand_separator: ''
-            prefix_suffix: true
+            format_plural: 'field'
           group_column: value
           group_columns: {  }
           group_rows: true
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 8addfd1..de1bfcc 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -13,6 +13,7 @@
 use Drupal\Core\Site\Settings;
 use Drupal\Core\StreamWrapper\PrivateStream;
 use Drupal\Core\StreamWrapper\PublicStream;
+use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
 use Drupal\system\SystemRequirements;
 use Symfony\Component\HttpFoundation\Request;
 
@@ -1845,5 +1846,121 @@ function system_update_8013() {
 }
 
 /**
+ * Update numeric field prefix/suffix configuration.
+ */
+function system_update_8014($sandbox) {
+  // Update prefix/suffix on numeric fields (types: float, decimal, integer)
+  // to new format_plural_string configuration. Also update associated
+  // formatters and widgets.
+
+  $views_fields_to_update = [];
+
+  // Locate all the numeric field storage config items.
+  foreach (['float', 'decimal', 'integer'] as $type) {
+    $field_storage_configs = \Drupal::entityManager()->getStorage('field_storage_config')->loadByProperties(array('type' => $type));
+    if (!$field_storage_configs) {
+      continue;
+    }
+    foreach ($field_storage_configs as $field_storage) {
+
+      // For each field storage item, locate the field config items.
+      $field_name = $field_storage->getName();
+      $field_configs = \Drupal::entityManager()->getStorage('field_config')->loadByProperties(array('field_name' => $field_name));
+      if (!$field_configs) {
+        continue;
+      }
+
+      // Save the field name to a list to update it in views outside this loop.
+      $views_fields_to_update[] = $field_name;
+
+      foreach ($field_configs as $field) {
+
+        // Update the prefix/suffix settings on the field config to the new
+        // format_plural_string setting.
+        $settings = $field->get('settings');
+        $prefix = isset($settings['prefix']) ?: '';
+        $suffix = isset($settings['suffix']) ?: '';
+        if ($prefix || $suffix) {
+          // In case they were using the previous system to separate
+          // plural values by |, make this into a proper format_plural
+          // object.
+          $prefixes = explode('|', $prefix);
+          $suffixes = explode('|', $suffix);
+          $length = max(count($prefixes), count($suffixes));
+          $strings = [];
+          for ($i = 0; $i < $length; $i++) {
+            $prefix = isset($prefixes[$i]) ?: $prefixes[0];
+            $suffix = isset($suffixes[$i]) ?: $suffixes[0];
+            $strings[] = $prefix . '@count' . $suffix;
+          }
+          $settings['format_plural_string'] = implode(PluralTranslatableMarkup::DELIMITER, $strings);
+        }
+        else {
+          $settings['format_plural_string'] = '';
+        }
+
+        unset($settings['prefix']);
+        unset($settings['suffix']);
+        $field->set('settings', $settings);
+        $field->save();
+
+        // Locate formatters on entity view displays for each field.
+        $properties = array(
+          'targetEntityType' => $field->getTargetEntityTypeId(),
+          'bundle' => $field->getTargetBundle()
+        );
+        if ($view_displays = \Drupal::entityManager()->getStorage('entity_view_display')->loadByProperties($properties)) {
+          foreach ($view_displays as $view_display) {
+
+            // Update the formatter setting prefix_suffix (Boolean) to be
+            // format_plural (values: 'field' (TRUE) or 'none' (FALSE)),
+            // and set format_plural_string to an empty string.
+            if ($component = $view_display->getComponent($field_name)) {
+              $settings = $component['settings'];
+              $settings['format_plural'] = (isset($settings['prefix_suffix']) && $settings['prefix_suffix']) ? 'field' : 'none';
+              unset($settings['prefix_suffix']);
+              $settings['format_plural_string'] = '';
+              $component['settings'] = $settings;
+              $view_display->setComponent($field_name, $component)->save();
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // Now do the same formatter update as above for formatters that are
+  // part of views. There isn't a way to query for which views might have
+  // them, so we have to go through all the displays on all the views.
+  if (count($views_fields_to_update)) {
+    $config_factory = \Drupal::configFactory();
+    foreach ($config_factory->listAll('views.view.') as $view_config_name) {
+      $view = $config_factory->getEditable($view_config_name);
+      $displays = $view->get('display');
+      $changed = FALSE;
+      foreach ($displays as $display_name => $display) {
+        if (!empty($display['display_options']['fields'])) {
+          foreach ($views_fields_to_update as $field_name) {
+            if (!isset($display['display_options']['fields'][$field_name])) {
+              continue;
+            }
+            $settings = $display['display_options']['fields'][$field_name]['settings'];
+            $settings['format_plural'] = (isset($settings['prefix_suffix']) && $settings['prefix_suffix']) ? 'field' : 'none';
+            unset($settings['prefix_suffix']);
+            $settings['format_plural_string'] = '';
+            $displays[$display_name]['display_options']['fields'][$field_name]['settings'] = $settings;
+            $changed = TRUE;
+          }
+        }
+      }
+      if ($changed) {
+        $view->set('display', $displays);
+        $view->save();
+      }
+    }
+  }
+}
+
+/**
  * @} End of "addtogroup updates-8.0.0-beta".
  */
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml
index 96d0559..a99eb9a 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml
@@ -140,7 +140,7 @@ display:
           type: number_integer
           settings:
             thousand_separator: ''
-            prefix_suffix: true
+            format_plural: 'field'
           group_column: value
           group_columns: {  }
           group_rows: true
diff --git a/core/modules/views/src/Entity/Render/EntityFieldRenderer.php b/core/modules/views/src/Entity/Render/EntityFieldRenderer.php
index f2a3778..95922bd 100644
--- a/core/modules/views/src/Entity/Render/EntityFieldRenderer.php
+++ b/core/modules/views/src/Entity/Render/EntityFieldRenderer.php
@@ -195,6 +195,7 @@ protected function buildFields(array $values) {
 
     if ($values && ($field_ids = $this->getRenderableFieldIds())) {
       $entity_type_id = $this->getEntityTypeId();
+      $settings_langcode = $this->view->storage->language()->getId();
 
       // Collect the entities for the relationship, fetch the right translation,
       // and group by bundle. For each result row, the corresponding entity can
@@ -231,6 +232,7 @@ protected function buildFields(array $values) {
             'targetEntityType' => $entity_type_id,
             'bundle' => $bundle,
             'status' => TRUE,
+            'langcode' => $settings_langcode,
           ]);
           foreach ($display_fields['field_ids'] as $field) {
             $display->setComponent($field->definition['field_name'], [
diff --git a/core/modules/views/src/Plugin/views/field/Field.php b/core/modules/views/src/Plugin/views/field/Field.php
index 33253d1..9d0b6ec 100644
--- a/core/modules/views/src/Plugin/views/field/Field.php
+++ b/core/modules/views/src/Plugin/views/field/Field.php
@@ -471,6 +471,8 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     $format = $this->options['type'];
 
     $settings = $this->options['settings'] + $this->formatterPluginManager->getDefaultSettings($format);
+    $settings_langcode = $this->view->storage->language()->getId();
+    $settings['_settings_langcode'] = $settings_langcode;
 
     $options = array(
       'field_definition' => $field,
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml
index ec19b13..c391c25 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml
@@ -180,7 +180,7 @@ display:
           type: number_integer
           settings:
             thousand_separator: ''
-            prefix_suffix: true
+            format_plural: 'field'
           group_column: value
           group_columns: {  }
           group_rows: true
