diff --git a/modules/field.views.inc b/modules/field.views.inc
index d93106f..57a8876 100644
--- a/modules/field.views.inc
+++ b/modules/field.views.inc
@@ -13,6 +13,9 @@
 
 /**
  * Implements hook_views_data()
+ *
+ * Field modules can implement hook_field_views_data() to override
+ * the default behavior for adding fields.
  */
 function field_views_data() {
   $data = array();
@@ -38,6 +41,27 @@ function field_views_data() {
 }
 
 /**
+ * Implements hook_views_data_alter()
+ *
+ * Field modules can implement hook_field_views_data_views_data_alter() to
+ * alter the views data on a per field basis. This is weirdly named so as
+ * not to conflict with the drupal_alter('field_views_data') in
+ * field_views_data.
+ */
+function field_views_data_alter(&$data) {
+  foreach (field_info_fields() as $field) {
+    if ($field['storage']['type'] != 'field_sql_storage') {
+      continue;
+    }
+
+    $function = $field['module'] . '_field_views_data_views_data_alter';
+    if (function_exists($function)) {
+      $function($data, $field);
+    }
+  }
+}
+
+/**
  * Returns the label of a certain field.
  *
  * Therefore it looks up in all bundles to find the most used instance.
diff --git a/modules/field/views_handler_relationship_entity_reverse.inc b/modules/field/views_handler_relationship_entity_reverse.inc
new file mode 100644
index 0000000..1189a36
--- /dev/null
+++ b/modules/field/views_handler_relationship_entity_reverse.inc
@@ -0,0 +1,74 @@
+<?php
+/**
+ * @file
+ * Views' relationship handlers.
+ */
+
+class views_handler_relationship_entity_reverse extends views_handler_relationship  {
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    $this->field_info = field_info_field($this->definition['field_name']);
+  }
+
+  /**
+   * Called to implement a relationship in a query.
+   */
+  function query() {
+    $this->ensure_my_table();
+    // First, relate our base table to the current base table to the
+    // field, using the base table's id field to the field's column.
+    $views_data = views_fetch_data($this->table);
+    $left_field = $views_data['table']['base']['field'];
+
+    $first = array(
+      'left_table' => $this->table_alias,
+      'left_field' => $left_field,
+      'table' => $this->definition['field table'],
+      'field' => $this->definition['field field'],
+    );
+    if (!empty($this->options['required'])) {
+      $first['type'] = 'INNER';
+    }
+
+    if (!empty($this->definition['join_handler']) && class_exists($this->definition['join_handler'])) {
+      $first_join = new $this->definition['join_handler'];
+    }
+    else {
+      $first_join = new views_join();
+    }
+    $first_join->definition = $first;
+    $first_join->construct();
+    $first_join->adjusted = TRUE;
+
+    $this->first_alias = $this->query->add_table($this->definition['field table'], $this->relationship, $first_join);
+
+    // Second, relate the field table to the entity specified using
+    // the entity id on the field table and the entity's id field.
+    $second = array(
+      'left_table' => $this->first_alias,
+      'left_field' => 'entity_id',
+      'table' => $this->definition['base'],
+      'field' => $this->definition['base field'],
+    );
+
+    if (!empty($this->options['required'])) {
+      $second['type'] = 'INNER';
+    }
+
+    if (!empty($this->definition['join_handler']) && class_exists($this->definition['join_handler'])) {
+      $second_join = new $this->definition['join_handler'];
+    }
+    else {
+      $second_join = new views_join();
+    }
+    $second_join->definition = $second;
+    $second_join->construct();
+    $second_join->adjusted = TRUE;
+
+    // use a short alias for this:
+    $alias = $this->definition['field_name'] . '_' . $this->table;
+
+    $this->alias = $this->query->add_relationship($alias, $second_join, $this->definition['base'], $this->relationship);
+  }
+}
diff --git a/modules/taxonomy.views.inc b/modules/taxonomy.views.inc
index 849de23..2e84447 100644
--- a/modules/taxonomy.views.inc
+++ b/modules/taxonomy.views.inc
@@ -395,24 +395,56 @@ function taxonomy_field_views_data($field) {
   $data = field_views_field_default_views_data($field);
   foreach ($data as $table_name => $table_data) {
     foreach ($table_data as $field_name => $field_data) {
-      if (!in_array($field_name, array('table', 'entity_id', 'revision_id'))) {
-        $data[$table_name][$field_name]['relationship'] = array(
-          'handler' => 'views_handler_relationship',
-          'base' => 'taxonomy_term_data',
-          'base field' => 'tid',
-          'label' => t('term from !field_name', array('!field_name' => $field['field_name'])),
-        );
-      }
       if (isset($field_data['filter'])) {
         $data[$table_name][$field_name]['filter']['handler'] = 'views_handler_filter_term_node_tid';
         $data[$table_name][$field_name]['filter']['vocabulary'] = $field['settings']['allowed_values'][0]['vocabulary'];
       }
     }
+
+    // Add the relationship only on the tid field.
+    $data[$table_name][$field['field_name'] . '_tid']['relationship'] = array(
+      'handler' => 'views_handler_relationship',
+      'base' => 'taxonomy_term_data',
+      'base field' => 'tid',
+      'label' => t('term from !field_name', array('!field_name' => $field['field_name'])),
+    );
+
   }
+
   return $data;
 }
 
 /**
+ * Implements hook_field_views_data_views_data_alter().
+ *
+ * Views integration to provide reverse relationships on term references.
+ */
+function taxonomy_field_views_data_views_data_alter(&$data, $field) {
+  foreach ($field['bundles'] as $entity_type => $bundles) {
+    $entity_info = entity_get_info($entity_type);
+    $pseudo_field_name = 'reverse_' . $field['field_name'] . '_' . $entity_type;
+
+    list($label, $all_labels) = field_views_field_label($field['field_name']);
+    $entity = $entity_info['label'];
+    if ($entity == t('Node')) {
+      $entity = t('Content');
+    }
+
+    $data['taxonomy_term_data'][$pseudo_field_name]['relationship'] = array(
+      'title' => t('@entity using @field', array('@entity' => $entity, '@field' => $label)),
+      'help' => t('Relate each @entity with a @field set to the term.', array('@entity' => $entity, '@field' => $label)),
+      'handler' => 'views_handler_relationship_entity_reverse',
+      'field_name' => $field['field_name'],
+      'field table' => _field_sql_storage_tablename($field),
+      'field field' => $field['field_name'] . '_tid',
+      'base' => $entity_info['base table'],
+      'base field' => $entity_info['entity keys']['id'],
+      'label' => t('!field_name', array('!field_name' => $field['field_name'])),
+    );
+  }
+}
+
+/**
  * Implements hook_views_plugins
  */
 function taxonomy_views_plugins() {
diff --git a/views.info b/views.info
index bd298d2..a8f11f7 100644
--- a/views.info
+++ b/views.info
@@ -86,6 +86,7 @@ files[] = modules/comment/views_plugin_row_comment_rss.inc
 files[] = modules/comment/views_plugin_row_comment_view.inc
 files[] = modules/contact/views_handler_field_contact_link.inc
 files[] = modules/field/views_handler_field_field.inc
+files[] = modules/field/views_handler_relationship_entity_reverse.inc
 files[] = modules/field/views_handler_filter_field_list.inc
 files[] = modules/filter/views_handler_field_filter_format_name.inc
 files[] = modules/locale/views_handler_argument_locale_group.inc
