diff --git a/config/schema/address.schema.yml b/config/schema/address.schema.yml
index 7f8cf16..e63a3da 100644
--- a/config/schema/address.schema.yml
+++ b/config/schema/address.schema.yml
@@ -138,6 +138,11 @@ field.widget.settings.address_default:
     default_country:
       type: string
       label: 'Default country'
+    preferred_countries:
+      type: sequence
+      label: 'Preferred countries'
+      sequence:
+        - type: string
 
 field.widget.settings.address_zone_default:
   type: mapping
@@ -150,6 +155,19 @@ field.widget.settings.address_zone_default:
 views.filter.country_code:
   type: views.filter.in_operator
   label: 'Country'
+  mapping:
+    preferred_countries:
+      type: mapping
+      mapping:
+      country_list:
+        type: string
+        label: 'Preferred countries list'
+      label_main:
+        type: string
+        label: 'Preferred countries main label'
+      label_other:
+        type: string
+        label: 'Preferred countries other label'
 
 views.filter.administrative_area:
   type: views.filter.in_operator
diff --git a/src/Element/Address.php b/src/Element/Address.php
index 929dd01..d962bdf 100644
--- a/src/Element/Address.php
+++ b/src/Element/Address.php
@@ -159,6 +159,7 @@ class Address extends FormElement {
       '#type' => 'address_country',
       '#title' => t('Country'),
       '#available_countries' => $element['#available_countries'],
+      '#preferred_countries' => $element['#preferred_countries'],
       '#default_value' => $element['#default_value']['country_code'],
       '#required' => $element['#required'],
       '#limit_validation_errors' => [],
diff --git a/src/Element/Country.php b/src/Element/Country.php
index bc044a7..48facd9 100644
--- a/src/Element/Country.php
+++ b/src/Element/Country.php
@@ -80,6 +80,27 @@ class Country extends FormElement {
     }
 
     $element['#tree'] = TRUE;
+
+    if (!empty($element['#preferred_countries'])) {
+      $preferred_countries = [];
+      foreach ($element['#preferred_countries'] as $preferred_country_code) {
+        if (isset($country_list[$preferred_country_code])) {
+          $preferred_countries[$preferred_country_code] = $country_list[$preferred_country_code];
+          unset($country_list[$preferred_country_code]);
+        }
+      }
+      // @todo Should these be configurable?
+      $preferred_label = (string) t('Preferred');
+      $other_label = (string) t('Other');
+      $country_options = [
+        $preferred_label => $preferred_countries,
+        $other_label => $country_list,
+      ];
+    }
+    else {
+      $country_options = $country_list;
+    }
+
     // Hide the dropdown when there is only one possible value.
     if (count($country_list) == 1 && $element['#required']) {
       $element['country_code'] = [
@@ -91,7 +112,7 @@ class Country extends FormElement {
       $element['country_code'] = [
         '#type' => 'select',
         '#title' => $element['#title'],
-        '#options' => $country_list,
+        '#options' => $country_options,
         '#default_value' => $element['#default_value'],
         '#required' => $element['#required'],
         '#limit_validation_errors' => [],
diff --git a/src/Plugin/Field/FieldWidget/AddressDefaultWidget.php b/src/Plugin/Field/FieldWidget/AddressDefaultWidget.php
index 31ebb68..0779686 100644
--- a/src/Plugin/Field/FieldWidget/AddressDefaultWidget.php
+++ b/src/Plugin/Field/FieldWidget/AddressDefaultWidget.php
@@ -101,6 +101,7 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
   public static function defaultSettings() {
     return [
       'default_country' => NULL,
+      'preferred_countries' => [],
     ] + parent::defaultSettings();
   }
 
@@ -109,6 +110,10 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
    */
   public function settingsForm(array $form, FormStateInterface $form_state) {
     $country_list = $this->countryRepository->getList();
+    $available_countries = $this->getFieldSetting('available_countries');
+    if (!empty($available_countries)) {
+      $country_list = array_intersect_key($country_list, $available_countries);
+    }
     $element = [];
     $element['default_country'] = [
       '#type' => 'select',
@@ -117,6 +122,15 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
       '#default_value' => $this->getSetting('default_country'),
       '#empty_value' => '',
     ];
+    $element['preferred_countries'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Preferred countries'),
+      '#options' => $country_list,
+      '#default_value' => $this->getSetting('preferred_countries'),
+      '#empty_value' => '',
+      '#multiple' => TRUE,
+      '#size' => 10,
+    ];
 
     return $element;
   }
@@ -139,6 +153,18 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
     $summary = [];
     $summary['default_country'] = $this->t('Default country: @country', ['@country' => $default_country]);
 
+    // Display summary for preferred countries setting.
+    $preferred_countries = $this->getSetting('preferred_countries');
+    if (!empty($preferred_countries)) {
+      if (!isset($country_list)) {
+        $country_list = $this->countryRepository->getList();
+      }
+      foreach ($preferred_countries as &$preferred_country) {
+        $preferred_country = $country_list[$preferred_country];
+      }
+      $summary['preferred_countries'] = $this->t('Preferred countries: @countries', array('@countries' => implode(', ', $preferred_countries)));
+    }
+
     return $summary;
   }
 
@@ -202,6 +228,9 @@ class AddressDefaultWidget extends WidgetBase implements ContainerFactoryPluginI
       '#default_value' => $value,
       '#required' => $this->fieldDefinition->isRequired(),
       '#available_countries' => $item->getAvailableCountries(),
+      // #preferred_countries is from a widget setting, not a field setting.
+      '#preferred_countries' => $this->getSetting('preferred_countries'),
+      // #used_fields is from a field setting, not a widget setting.
       '#used_fields' => $this->getFieldSetting('fields'),
     ];
 
diff --git a/src/Plugin/views/filter/CountryCode.php b/src/Plugin/views/filter/CountryCode.php
index aa2da72..37618b9 100644
--- a/src/Plugin/views/filter/CountryCode.php
+++ b/src/Plugin/views/filter/CountryCode.php
@@ -2,6 +2,9 @@
 
 namespace Drupal\address\Plugin\views\filter;
 
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\views\Plugin\views\filter\InOperator;
+
 /**
  * Filter by country.
  *
@@ -22,4 +25,90 @@ class CountryCode extends CountryAwareInOperatorBase {
     return $this->valueOptions;
   }
 
+  /**
+   * {@inheritdoc}
+   *
+   * We implement preferred_countries here, not at the level of
+   * getValueOptions(), so as not to break the admin UI when configuring the
+   * filter, e.g. when trying to select default country values. That doesn't
+   * handle nested arrays properly. So preferred_countries and the opt-group
+   * support only happens on the exposed form element.
+   */
+  public function buildExposedForm(&$form, FormStateInterface $form_state) {
+    parent::buildExposedForm($form, $form_state);
+
+    if (!empty($this->options['preferred_countries']['country_list'])) {
+      $form_key = $this->options['expose']['identifier'];
+      $country_list = $form[$form_key]['#options'];
+
+      $preferred_countries = [];
+      if (!empty($country_list['All'])) {
+        $preferred_countries['All'] = $country_list['All'];
+        unset($country_list['All']);
+      }
+      foreach ($this->options['preferred_countries']['country_list'] as $preferred_country_code) {
+        if (isset($country_list[$preferred_country_code])) {
+          $preferred_countries[$preferred_country_code] = $country_list[$preferred_country_code];
+          unset($country_list[$preferred_country_code]);
+        }
+      }
+      $preferred_label = $this->options['preferred_countries']['label_main'];
+      $other_label = $this->options['preferred_countries']['label_other'];
+      $form[$form_key]['#options'] = [
+        $preferred_label => $preferred_countries,
+        $other_label => $country_list,
+      ];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+    $options['preferred_countries'] = [
+      'contains' => [
+        'country_list' => ['default' => ''],
+        'label_main' => ['default' => (string) t('Preferred')],
+        'label_other' => ['default' => (string) t('Other')],
+      ],
+    ];
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
+    parent::buildOptionsForm($form, $form_state);
+    $form['preferred_countries'] = [
+      '#type' => 'container',
+      '#states' => [
+        'visible' => [
+          ':input[name="options[expose_button][checkbox][checkbox]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['preferred_countries']['country_list'] = [
+      '#type' => 'select',
+      '#title' => t('Preferred countries'),
+      '#options' => $this->getAvailableCountries(),
+      '#multiple' => TRUE,
+      '#default_value' => $this->options['preferred_countries']['country_list'],
+    ];
+    $form['preferred_countries']['label_main'] = [
+      '#type' => 'textfield',
+      '#title' => t('Preferred countries main label'),
+      '#description' => t('Define the label for perferred countries (at the top of the list).'),
+      '#default_value' => $this->options['preferred_countries']['label_main'],
+    ];
+    $form['preferred_countries']['label_other'] = [
+      '#type' => 'textfield',
+      '#title' => t('Preferred countries other label'),
+      '#description' => t('Define the label for other countries (at the bottom of the list).'),
+      '#default_value' => $this->options['preferred_countries']['label_other'],
+    ];
+
+  }
+
 }
