diff --git a/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php b/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php
index 0752494..a1e149b 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php
@@ -58,6 +58,17 @@ 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 are using the alternate PhpSelectionBase as default
+      // plugin to allow filtering the target entity list by label method.
+      // PhpSelectionBase is more expensive than SelectionBase because the
+      // second one queries directly the database without any additional PHP
+      // processing.
+      // @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..8c090b2
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/PhpSelectionBase.php
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\Plugin\EntityReferenceSelection\PhpSelectionBase.
+ */
+
+namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
+
+/**
+ * Alternative default plugin implementation of the Entity Reference Selection
+ * plugin.
+ *
+ * This default plugin uses PHP for more advanced cases when the database 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) {
+    // Options returned by database query.
+    $options = parent::getReferenceableEntities($match, $match_operator, $limit);
+
+    // No input, return all.
+    if (empty($match)) {
+      return $options;
+    }
+
+    $storage = $this->entityManager->getStorage($this->configuration['target_type']);
+
+    // Filter target entities by label method.
+    foreach ($options as $bundle => $items) {
+      foreach ($items as $entity_id => $safe_label) {
+        $entity = $storage->load($entity_id);
+        if ($label = $entity->label()) {
+          $strpos_match = stripos($label, $match);
+          if ($match_operator == 'CONTAINS' && $strpos_match !== FALSE) {
+            continue;
+          }
+          elseif ($match_operator == 'STARTS_WITH' && $strpos_match === 0) {
+            continue;
+          }
+          // This matching operator doesn't exist in autocomplete widget but is
+          // used as an API hack in parent::validateAutocompleteInput() to get
+          // the exact matches of an input string, thus we need to support it as
+          // well here.
+          // @see \Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase::validateAutocompleteInput()
+          elseif ($match_operator == '=' && $label == $match) {
+            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;
+  }
+
+}
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']));
+  }
+
+}
