diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php
index b472b8f..f8b4c45 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php
@@ -424,7 +424,7 @@ protected function invokeHook($hook, EntityInterface $entity) {
    * Implements Drupal\Core\Entity\EntityStorageControllerInterface::getQueryServicename().
    */
   public function getQueryServicename() {
-    throw new \LogicException('Querying configuration entities is not supported.');
+    return 'entity.query.config';
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Config/Entity/Query/Condition.php b/core/lib/Drupal/Core/Config/Entity/Query/Condition.php
index b1d0d3c..8f80ec6 100644
--- a/core/lib/Drupal/Core/Config/Entity/Query/Condition.php
+++ b/core/lib/Drupal/Core/Config/Entity/Query/Condition.php
@@ -8,29 +8,73 @@
 namespace Drupal\Core\Config\Entity\Query;
 
 use Drupal\Core\Entity\Query\ConditionBase;
+use Drupal\Core\Entity\Query\ConditionInterface;
+use Drupal\Core\Database\Query\SelectInterface;
+use Drupal\Core\Database\Query\Condition as SqlCondition;
 
 class Condition extends ConditionBase {
 
   /**
-   * Compiles this conditional clause.
-   *
-   * @param $query
-   *   The query object this conditional clause belongs to.
+   * Implements Drupal\Core\Entity\Query\ConditionInterface::compile().
    */
-  public function compile($query) {
+  public function compile($conditionContainer) {
+    // If this is not the top level condition group then the sql query is
+    // added to the $conditionContainer object by this function itself. The
+    // SQL query object is only necessary to pass to Query::addField() so it
+    // can join tables as necessary. On the other hand, conditions need to be
+    // added to the $conditionContainer object to keep grouping.
+    if ($conditionContainer instanceof SelectInterface) {
+      $added = TRUE;
+      $sqlQuery = $conditionContainer;
+    }
+    else {
+      $added = FALSE;
+      $sqlQuery = $conditionContainer->sqlQuery;
+    }
 
+    foreach ($this->conditions as $condition) {
+      if ($condition['field'] instanceOf ConditionInterface) {
+        $sqlCondition = new SqlCondition($condition['field']->getConjunction());
+        // Add the SQL query to the object before calling this method again.
+        $sqlCondition->sqlQuery = $sqlQuery;
+        $condition['field']->compile($sqlCondition);
+        $sqlQuery->condition($sqlCondition);
+      }
+      else {
+        $and = strtoupper($this->conjunction) == 'AND';
+        $or = !$and;
+        $type = $or || $condition['operator'] == 'IS NULL' ? 'LEFT' : 'INNER';
+        #$this->translateCondition($condition);
+        if ($and || !$added) {
+          $alias = $conditionContainer->join('config_entity_denormalized', NULL, '%alias.entity_type = base_table.entity_type AND %alias.entity_id = base_table.entity_id');
+          $added = TRUE;
+        }
+        if ($and) {
+          $container = $conditionContainer;
+        }
+        else {
+          $container = new SqlCondition('AND');
+        }
+        $container->condition("$alias.name", $condition['field']);
+        $container->condition("$alias.value", $condition['value'], $condition['operator']);
+        if ($or) {
+          $conditionContainer->condition($container);
+        }
+      }
+    }
   }
 
   /**
-   * Implements \Drupal\Core\Entity\Query\QueryInterface::exists()
+   * Implements Drupal\Core\Entity\Query\ConditionInterface::exists().
    */
   public function exists($field, $langcode = NULL) {
+    return $this->condition($field, NULL, 'IS NOT NULL', $langcode);
   }
 
   /**
-   * Implements \Drupal\Core\Entity\Query\QueryInterface::notexists()
+   * Implements Drupal\Core\Entity\Query\ConditionInterface::notExists().
    */
   public function notExists($field, $langcode = NULL) {
+    return $this->condition($field, NULL, 'IS NULL', $langcode);
   }
-
-}
+}
\ No newline at end of file
diff --git a/core/lib/Drupal/Core/Config/Entity/Query/Denormalize.php b/core/lib/Drupal/Core/Config/Entity/Query/Denormalize.php
index e9ea2cc..0ca8357 100644
--- a/core/lib/Drupal/Core/Config/Entity/Query/Denormalize.php
+++ b/core/lib/Drupal/Core/Config/Entity/Query/Denormalize.php
@@ -34,6 +34,11 @@ class Denormalize implements EventSubscriberInterface {
    */
   protected $config;
 
+  /**
+   * @var \Drupal\Core\Database\Query\Insert
+   */
+  public $insert;
+
   public function __construct(Connection $connection) {
     $this->connection = $connection;
   }
@@ -46,19 +51,22 @@ public function configSave(ConfigEvent $event) {
     $txn = $this->connection->startTransaction();
     $this->configDelete($event);
     if ($this->entity_type) {
-      $this->connection->insert('ceqd')
-        ->fields('entity_type', 'entity_id', 'name', 'value')
-        ->values($this->flatten($this->config->get()))
-        ->execute();
+      $this->insert = $this->connection->insert('config_entity_denormalized')
+        ->fields(array('entity_type', 'entity_id', 'name', 'value'));
+      $this->values($this->config->get());
+      $this->insert->execute();
     }
   }
 
   public function configDelete(ConfigEvent $event) {
     $this->config = $event->getConfig();
     $name = $this->config->getName();
+    // @todo Remove this in http://drupal.org/node/1798732.
+    module_list();
     if ($this->entity_type = config_get_entity_type_by_name($name)) {
-      $this->entity_id = substr($name, strlen($this->entity_type) + 1);
-      $this->connection->delete('ceqd')
+      $entity_info = entity_get_info($this->entity_type);
+      $this->entity_id = substr($name, strlen($entity_info['config_prefix']) + 1);
+      $this->connection->delete('config_entity_denormalized')
         ->condition('entity_type', $this->entity_type)
         ->condition('entity_id', $this->entity_id)
         ->execute();
@@ -75,16 +83,15 @@ public function configDelete(ConfigEvent $event) {
    * @param string $prefix
    *   The current config prefix.
    */
-  protected function flatten($data, array &$values = array(), $prefix = '') {
+  protected function values($data, $prefix = '') {
     foreach ($data as $key => $value) {
       if (is_array($value)) {
-        $this->flatten($value, $values, "$key.");
+        $this->values($value, "$prefix$key.");
       }
       else {
-        $values[] = array($this->entity_type, $this->entity_id, "$prefix$key", $value);
+        $this->insert->values(array($this->entity_type, $this->entity_id, "$prefix$key", $value));
       }
     }
-    return $values;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Config/Entity/Query/Query.php b/core/lib/Drupal/Core/Config/Entity/Query/Query.php
index 8f10129..7d9245f 100644
--- a/core/lib/Drupal/Core/Config/Entity/Query/Query.php
+++ b/core/lib/Drupal/Core/Config/Entity/Query/Query.php
@@ -6,12 +6,36 @@
 
 class Query extends QueryBase {
   /**
+   * @var \Drupal\Core\Database\Connection
    */
-  public function execute() {
+  protected $connection;
+
+  /**
+   * @param string $entity_type
+   *   The entity type.
+   * @param string $conjunction
+   *   - AND: all of the conditions on the query need to match.
+   *   - OR: at least one of the conditions on the query need to match.
+   * @param \Drupal\Core\Database\Connection $connection
+   *   The database connection to run the query against.
+   */
+  public function __construct($entity_type, $conjunction, $connection) {
+    parent::__construct($entity_type, $conjunction);
+    $this->connection = $connection;
   }
 
   /**
+   * Implements Drupal\Core\Entity\Query\QueryInterface::conditionGroupFactory().
    */
   public function conditionGroupFactory($conjunction = 'AND') {
+    return new Condition($conjunction);
+  }
+
+  /**
+   * Implements Drupal\Core\Entity\Query\QueryInterface::execute().
+   */
+  public function execute() {
+    $sqlQuery = $this->connection->select('config_entity_denormalized', 'base_table', array('conjunction' => $this->conjunction));
+    $this->condition->compile($sqlQuery);
   }
 }
diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 2076707..e64dd5e 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -135,9 +135,15 @@ public function build(ContainerBuilder $container) {
     $this->registerTwig($container);
     $this->registerRouting($container);
 
-    // Add the entity query factory.
+    // Add the entity query factories.
     $container->register('entity.query', 'Drupal\Core\Entity\Query\QueryFactory')
       ->addArgument(new Reference('service_container'));
+    $container->register('entity.query.config', 'Drupal\Core\Config\Entity\Query\QueryFactory')
+      ->addArgument(new Reference('database'));
+    $container->register('entity.query.denormalize', 'Drupal\Core\Config\Entity\Query\Denormalize')
+      ->addArgument(new Reference('database'))
+      ->addTag('event_subscriber');
+
 
     $container->register('router.dumper', 'Drupal\Core\Routing\MatcherDumper')
       ->addArgument(new Reference('database'));
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
index b09df75..08997ae 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
@@ -132,6 +132,7 @@ public function containerBuild($container) {
     global $conf;
     // Keep the container object around for tests.
     $this->container = $container;
+    $container->removeDefinition('entity.query.denormalize');
     $container->register('lock', 'Drupal\Core\Lock\NullLockBackend');
     $conf['cache_classes'] = array('cache' => 'Drupal\Core\Cache\MemoryBackend');
     $container
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index b63ca46..8a8a49e 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -678,6 +678,45 @@ function system_schema() {
   $schema['cache_path'] = $schema['cache'];
   $schema['cache_path']['description'] = 'Cache table for path alias lookup.';
 
+  $schema['config_entity_denormalized'] = array(
+    'description' => 'This table is storing denormalized configuration entity objects for query purposes.',
+    'fields' => array(
+      'entity_type' => array(
+        'description' => 'Tne type of the config entity.',
+        'type' => 'varchar',
+        'length' => 32,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'entity_id' => array(
+        'description' => 'Tne ID of the config entity.',
+        'type' => 'varchar',
+        'length' => 64,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'name' => array(
+        'description' => 'The key of the key-value pair. As KEY is a SQL reserved keyword, name was chosen instead.',
+        'type' => 'varchar',
+        'length' => 237,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'value' => array(
+        'description' => 'The value.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+    ),
+    'primary key' => array('entity_type', 'entity_id', 'name'),
+    'index' => array(
+      'query_name' => array('entity_type', 'name', array('value', 64)),
+      'query_value' => array('entity_type', array('value', 64), 'name'),
+    ),
+  );
+
   $schema['flood'] = array(
     'description' => 'Flood controls the threshold of events, such as the number of contact attempts.',
     'fields' => array(
