diff --git a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
index b0791e2..b2f97dc 100644
--- a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
+++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
@@ -47,6 +47,16 @@ public function __construct($collection, Connection $connection, $table = 'key_v
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function has($key) {
+    return (bool) $this->connection->query('SELECT 1 FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection AND name = :key', array(
+      ':collection' => $this->collection,
+      ':key' => $key,
+    ))->fetchField();
+  }
+
+  /**
    * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::getMultiple().
    */
   public function getMultiple(array $keys) {
diff --git a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
index 91e7752..fb0b8b0 100644
--- a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
+++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
@@ -57,6 +57,17 @@ public function __construct($collection, Connection $connection, $table = 'key_v
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function has($key) {
+    return (bool) $this->connection->query('SELECT 1 FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection AND name = :key AND expire > :now', array(
+      ':collection' => $this->collection,
+      ':key' => $key,
+      ':now' => REQUEST_TIME,
+    ))->fetchField();
+  }
+
+  /**
    * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::getMultiple().
    */
   public function getMultiple(array $keys) {
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php
index 60c150c..39d1da0 100644
--- a/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php
@@ -21,6 +21,17 @@
   public function getCollectionName();
 
   /**
+   * Returns whether a given key exists in the store.
+   *
+   * @param string $key
+   *   The key to check.
+   *
+   * @return bool
+   *   TRUE if the key exists, FALSE otherwise.
+   */
+  public function has($key);
+
+  /**
    * Returns the stored value for a given key.
    *
    * @param string $key
diff --git a/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php
index e6e07ef..6e9b0f7 100644
--- a/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php
+++ b/core/lib/Drupal/Core/KeyValueStore/MemoryStorage.php
@@ -20,6 +20,13 @@ class MemoryStorage extends StorageBase {
   protected $data = array();
 
   /**
+   * {@inheritdoc}
+   */
+  public function has($key) {
+    return array_key_exists($key, $this->data);
+  }
+
+  /**
    * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::get().
    */
   public function get($key, $default = NULL) {
diff --git a/core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php b/core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php
index 29bcde6..a3704eb 100644
--- a/core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php
+++ b/core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php
@@ -34,6 +34,13 @@ public function __construct($collection) {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function has($key) {
+    return FALSE;
+  }
+
+  /**
    * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::get().
    */
   public function get($key, $default = NULL) {
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageExpirableTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageExpirableTest.php
index 19a261b..5f7365d 100644
--- a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageExpirableTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageExpirableTest.php
@@ -141,7 +141,9 @@ public function testExpiration() {
     $stores[0]->set('troubles', 'here to stay');
 
     // Only the non-expired item should be returned.
+    $this->assertFalse($stores[0]->has('yesterday'));
     $this->assertFalse($stores[0]->get('yesterday'));
+    $this->assertTrue($stores[0]->has('troubles'));
     $this->assertIdentical($stores[0]->get('troubles'), 'here to stay');
     $this->assertIdentical(count($stores[0]->getMultiple(array('yesterday', 'troubles'))), 1);
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/StorageTestBase.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/StorageTestBase.php
index 86e6ce8..f8c8de9 100644
--- a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/StorageTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/StorageTestBase.php
@@ -83,8 +83,10 @@ public function testCRUD() {
 
     // Verify that an item can be stored.
     $stores[0]->set('foo', $this->objects[0]);
+    $this->assertTrue($stores[0]->has('foo'));
     $this->assertIdenticalObject($this->objects[0], $stores[0]->get('foo'));
     // Verify that the other collection is not affected.
+    $this->assertFalse($stores[1]->has('foo'));
     $this->assertFalse($stores[1]->get('foo'));
 
     // Verify that an item can be updated.
@@ -100,9 +102,11 @@ public function testCRUD() {
 
     // Verify that an item can be deleted.
     $stores[0]->delete('foo');
+    $this->assertFalse($stores[0]->has('foo'));
     $this->assertFalse($stores[0]->get('foo'));
 
     // Verify that the other collection is not affected.
+    $this->assertTrue($stores[1]->has('foo'));
     $this->assertIdenticalObject($this->objects[2], $stores[1]->get('foo'));
     $stores[1]->delete('foo');
     $this->assertFalse($stores[1]->get('foo'));
