diff --git a/entity_translation.admin.inc b/entity_translation.admin.inc
index 3bdf410..7beafdc 100644
--- a/entity_translation.admin.inc
+++ b/entity_translation.admin.inc
@@ -17,6 +17,18 @@ function entity_translation_admin_form($form, $form_state) {
     '#description' => t('When language fallback is enabled, if a translation is not available for the requested language an existing one will be displayed.'),
     '#default_value' => variable_get('locale_field_language_fallback', TRUE),
   );
+  
+  $form['entity_translation_display_unavailable'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Display a warning message for unavailable translations'),
+    '#description' => t('If checked, a themeable warning message will replace the entity when a translation is unavailable.'),
+    '#default_value' => variable_get('entity_translation_display_unavailable', TRUE),
+    '#states' => array(
+      'visible' => array(
+        ':input[name="locale_field_language_fallback"]' => array('checked' => FALSE),
+      ),
+    ),
+  );
 
   $form['entity_translation_show_fallback_on_overview_pages'] = array(
     '#type' => 'checkbox',
diff --git a/entity_translation.module b/entity_translation.module
index f7ca0ab..552407c 100644
--- a/entity_translation.module
+++ b/entity_translation.module
@@ -939,6 +939,76 @@ function entity_translation_field_language_alter(&$display_language, $context) {
 }
 
 /**
+ * Implements hook_query_alter().
+ * @param QueryAlterableInterface $query
+ *
+ * Rewrite entity queries so if language fallback and the display of unavailable
+ * translations are disabled, untranslated nodes are not listed.
+ */
+function entity_translation_query_alter(QueryAlterableInterface $query) {
+  $only_availables = !variable_get('locale_field_language_fallback', TRUE) && !variable_get('entity_translation_display_unavailable', TRUE);
+  if($only_availables) {
+    $entity_info = entity_get_info();
+    $entity_tables = entity_translation_get_base_tables($entity_info);
+    // Read the base table from the query if available or default to the first
+    // table in the query's tables array.
+    if (!$base_table = $query->getMetaData('base_table')) {
+      $tables = $query->getTables();
+      $base_table = array_shift($tables);
+      $base_table = $base_table['table'];
+    }
+
+    $entity_type = array_search($base_table, $entity_tables);
+    if (in_array($base_table, $entity_tables) && entity_translation_enabled($entity_type)
+      && !(user_access('translate any entity') || user_access("translate $entity_type entities"))) {
+      // Get the node table alias if this request is on a node table.
+      foreach ($query->getTables() as $table) {
+        if ($table['join type'] == NULL && in_array($table['table'], $entity_tables)) {
+          $entity_alias = empty($table['alias']) ? $table['table'] : $table['alias'];
+        }
+      }
+
+      if (isset($entity_alias)) {
+        // @TODO: hack. See http://drupal.org/node/1452642.
+        // There's a status field in entity_translation table,
+        // similar to the node table, and conditions are not prefixed by
+        // the node alias in node.module.
+        // So we have to add the node alias to avoid errors.
+        $conditions = &$query->conditions();
+        foreach ($conditions as $key => $condition) {
+          if(is_array($condition) && isset($condition['field']) && is_string($condition['field']) && !empty($condition['field'])) {
+            $field_aliased = is_string($condition['field']) && strpos($condition['field'], '.') !== FALSE;
+            if (!$field_aliased) {
+              $conditions[$key]['field'] = $entity_alias . '.' . $condition['field'];
+            }
+          }
+        }
+        $entity_key = $entity_info[array_search($base_table, $entity_tables)]['entity keys']['id'];
+        $query->join('entity_translation', 'et', "et.entity_id = $entity_alias.$entity_key AND et.entity_type = :entity_type", array(':entity_type' => $entity_type));
+        $query->condition('et.status', 1, '=');
+        $query->addTag('entity_translation');
+      }
+    }
+  }
+}
+
+function entity_translation_get_base_tables($entity_info) {
+  static $drupal_static_fast;
+  if (!isset($drupal_static_fast)) {
+    $drupal_static_fast['entity_base_tables'] = &drupal_static(__FUNCTION__);
+  }
+  $entity_tables = &$drupal_static_fast['entity_base_tables'];
+  if (empty($entity_tables)) {
+    $entity_tables = array();
+    foreach ($entity_info as $key => $value) {
+      $entity_tables[$key] = $value['base table'];
+    }
+  }
+
+  return $entity_tables;
+}
+
+/**
  * Implements hook_field_attach_view_alter().
  *
  * Hide the entity if no translation is available for the current language and
