diff --git a/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php b/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php
index 0752494..67789af 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php
@@ -58,7 +58,20 @@ public function getDerivativeDefinitions($base_plugin_definition) {
       $this->derivatives[$entity_type_id]['entity_types'] = array($entity_type_id);
       $this->derivatives[$entity_type_id]['label'] = t('@entity_type selection', array('@entity_type' => $entity_type->getLabel()));
       $this->derivatives[$entity_type_id]['base_plugin_label'] = (string) $base_plugin_definition['label'];
+
+      // If the entity type doesn't provide a 'label' key in its plugin
+      // definition, we have to use the alternate PhpSelectionBase class as
+      // default plugin, which allows filtering the target entities by their
+      // label() method. The major downside of PhpSelectionBase is that it is
+      // more expensive performance-wise than SelectionBase because it has to
+      // load the target entities in order to perform the filtering process.
+      //
+      // @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\PhpSelectionBase
+      if (!$entity_type->hasKey('label')) {
+        $this->derivatives[$entity_type_id]['class'] = 'Drupal\Core\Entity\Plugin\EntityReferenceSelection\PhpSelectionBase';
+      }
     }
+
     return parent::getDerivativeDefinitions($base_plugin_definition);
   }
 
diff --git a/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/PhpSelectionBase.php b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/PhpSelectionBase.php
new file mode 100644
index 0000000..16d35a5
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/PhpSelectionBase.php
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\Plugin\EntityReferenceSelection\PhpSelectionBase.
+ */
+
+namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
+
+use Drupal\Component\Utility\Unicode;
+
+/**
+ * Defines an alternative to the default Entity Reference Selection plugin.
+ *
+ * This selection plugin uses PHP for more advanced cases when the entity query
+ * cannot filter properly, for example when the target entity type has no
+ * 'label' key provided in the entity type plugin definition.
+ *
+ * @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase
+ * @see \Drupal\Core\Entity\Plugin\Derivative\SelectionBase
+ */
+class PhpSelectionBase extends SelectionBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
+    // Start with the selection results returned by the entity query.
+    $options = parent::getReferenceableEntities($match, $match_operator, $limit);
+
+    // No input, return everything.
+    if ($match === NULL) {
+      return $options;
+    }
+
+    // Filter target entities by the output of their label() method.
+    foreach ($options as $bundle => $items) {
+      foreach ($items as $entity_id => $safe_label) {
+        // The entity label is escaped by the parent method.
+        $original_label = htmlspecialchars_decode($safe_label, ENT_QUOTES);
+
+        if ($this->matchLabel($match, $match_operator, $original_label)) {
+          continue;
+        }
+
+        // Remove unmatched option.
+        unset($options[$bundle][$entity_id]);
+      }
+    }
+
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function countReferenceableEntities($match = NULL, $match_operator = 'CONTAINS') {
+    $count = 0;
+    foreach ($this->getReferenceableEntities($match, $match_operator) as $items) {
+      $count += count($items);
+    }
+
+    return $count;
+  }
+
+  /**
+   * Matches an entity label to an input string.
+   *
+   * @param string $match
+   *   The string to compare.
+   * @param string $match_operator
+   *   The comparison operator.
+   * @param string $label
+   *   The entity label to match against.
+   *
+   * @return bool
+   *   TRUE when matches, FALSE otherwise.
+   */
+  protected function matchLabel($match, $match_operator, $label) {
+    // We always want a case-insensitive match.
+    if (!is_bool($label)) {
+      $label = Unicode::strtolower($label);
+    }
+
+    switch ($match_operator) {
+      case '=':
+        return $label == $match;
+      case '>':
+        return $label > $match;
+      case '<':
+        return $label < $match;
+      case '>=':
+        return $label >= $match;
+      case '<=':
+        return $label <= $match;
+      case '<>':
+        return $label != $match;
+      case 'IN':
+        return array_search($label, $match) !== FALSE;
+      case 'NOT IN':
+        return array_search($label, $match) === FALSE;
+      case 'STARTS_WITH':
+        return strpos($label, $match) === 0;
+      case 'CONTAINS':
+        return strpos($label, $match) !== FALSE;
+      case 'ENDS_WITH':
+        return substr($label, -strlen($match)) === (string) $match;
+      case 'IS NOT NULL':
+        return TRUE;
+      case 'IS NULL':
+        return FALSE;
+      default:
+        // Invalid match operator.
+        return FALSE;
+    }
+  }
+
+}
diff --git a/core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionReferenceableTest.php b/core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionReferenceableTest.php
new file mode 100644
index 0000000..d7dc8d6
--- /dev/null
+++ b/core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionReferenceableTest.php
@@ -0,0 +1,110 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\Entity\EntityReferenceSelection\EntityReferenceSelectionReferenceableTest.
+ */
+
+namespace Drupal\system\Tests\Entity\EntityReferenceSelection;
+
+use Drupal\Component\Utility\Unicode;
+use Drupal\entity_reference\Tests\EntityReferenceTestTrait;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\node\Entity\NodeType;
+use Drupal\simpletest\KernelTestBase;
+
+/**
+ * Tests entity reference selection plugins.
+ *
+ * @group entity_reference
+ */
+class EntityReferenceSelectionReferenceableTest extends KernelTestBase {
+
+  use EntityReferenceTestTrait;
+
+  /**
+   * A random node-type.
+   *
+   * @var string
+   */
+  protected $nodeType;
+
+  /**
+   * The entity reference field name.
+   *
+   * @var string
+   */
+  protected $fieldName;
+
+  /**
+   * Modules to be installed.
+   *
+   * @var array
+   */
+  public static $modules = ['system', 'user', 'field', 'entity_reference', 'node', 'block'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    /** @var \Drupal\Core\Entity\EntityStorageInterface $block_storage */
+    $block_storage = $this->container->get('entity.manager')
+      ->getStorage('block');
+
+    // Create a new node-type.
+    $this->nodeType = Unicode::strtolower($this->randomMachineName());
+    NodeType::create([
+      'type' => $this->nodeType,
+      'name' => $this->randomString(),
+    ])->save();
+
+    // Create an entity reference field targeting 'block' entities.
+    $this->fieldName = Unicode::strtolower($this->randomMachineName());
+    $this->createEntityReferenceField('node', $this->nodeType, $this->fieldName, $this->randomString(), 'block', 'default');
+
+    // Create 3 blocks to be referenced by the field.
+    foreach (['abc', 'xyz', 'xyabz'] as $label) {
+      $block_storage->create([
+        'id' => Unicode::strtolower($this->randomMachineName()),
+        'settings' => ['label' => $label],
+        'plugin' => 'system_menu_block:admin',
+      ])->save();
+    }
+  }
+
+  /**
+   * Tests values returned by SelectionInterface::getReferenceableEntities()
+   * when the target entity type has no 'label' key.
+   */
+  public function testReferenceablesWithNoLabelKey() {
+    $field_config = FieldConfig::loadByName('node', $this->nodeType, $this->fieldName);
+    /** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface $handler */
+    $handler = $this->container->get('plugin.manager.entity_reference_selection')->getSelectionHandler($field_config);
+
+    // Get all referenceables. Expecting 3 items.
+    $referenceables = $handler->getReferenceableEntities();
+    $this->assertIdentical(count($referenceables['block']), 3);
+
+    // Get referenceables containing 'w'. Expecting no item.
+    $referenceables = $handler->getReferenceableEntities('w');
+    $this->assertTrue(empty($referenceables['block']));
+
+    // Get referenceables starting with 'w'. Expecting no item.
+    $referenceables = $handler->getReferenceableEntities('w', 'STARTS_WITH');
+    $this->assertTrue(empty($referenceables['block']));
+
+    // Get referenceables containing 'ab'. Expecting 2 items ('abc', 'xyabz').
+    $referenceables = $handler->getReferenceableEntities('ab');
+    $this->assertIdentical(count($referenceables['block']), 2);
+    $this->assertTrue((bool) array_search('abc', $referenceables['block']));
+    $this->assertTrue((bool) array_search('xyabz', $referenceables['block']));
+
+    // Get referenceables starting with 'A'. Expecting 1 item ('abc').
+    $referenceables = $handler->getReferenceableEntities('A', 'STARTS_WITH');
+    $this->assertIdentical(count($referenceables['block']), 1);
+    $this->assertTrue((bool) array_search('abc', $referenceables['block']));
+  }
+
+}
