diff --git a/diff.pages.inc b/diff.pages.inc
index aee9b1b..64f8106 100644
--- a/diff.pages.inc
+++ b/diff.pages.inc
@@ -248,6 +248,7 @@ function _diff_body_rows($old_node, $new_node) {
   drupal_add_css(drupal_get_path('module', 'diff') . '/diff.css');
 
   module_load_include('inc', 'diff', 'includes/node');
+  module_load_include('inc', 'diff', 'includes/taxonomy');
 
   $rows = array();
   $any_visible_change = FALSE;
diff --git a/includes/taxonomy.inc b/includes/taxonomy.inc
new file mode 100644
index 0000000..0d0e8e4
--- /dev/null
+++ b/includes/taxonomy.inc
@@ -0,0 +1,75 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Implements hook_diff() for taxonomy.module
+ */
+
+/**
+ * Implements hook_diff() for taxonomy.module
+ */
+function taxonomy_diff($old_node, $new_node) {
+
+  $result = array();
+  $type = node_type_get_type($new_node);
+
+  // @TODO: abstract this to work with all field types and/or split this
+  // integration out to be more generic.
+  $instances = field_info_instances('node', field_extract_bundle('node', $type));
+  foreach ($instances as $instance) {
+    if ($instance['display']['default']['module'] == 'taxonomy') {
+      $field_name = $instance['field_name'];
+      $langcode = field_language('node', $new_node, $field_name);
+      
+      // Prepare term lists for multiple fields
+      $new_terms = array(); // Tags specific for diff review before save
+      $new_node_terms = array();
+      $old_node_terms = array();
+      if (isset($new_node->{$field_name}[$langcode]) && !empty($new_node->{$field_name}[$langcode])) {
+        foreach (array_keys($new_node->{$field_name}[$langcode]) as $delta) {
+          if ($new_node->{$field_name}[$langcode][$delta]['tid'] != 'autocreate') {
+            $new_node_terms[$new_node->{$field_name}[$langcode][$delta]['tid']] = TRUE;
+          } else {
+            $new_terms[] = $new_node->{$field_name}[$langcode][$delta]['name'];
+          }
+        }
+      }
+      if (isset($old_node->{$field_name}[$langcode]) && !empty($old_node->{$field_name}[$langcode])) {
+        foreach (array_keys($old_node->{$field_name}[$langcode]) as $delta) {
+          $old_node_terms[$old_node->{$field_name}[$langcode][$delta]['tid']] = TRUE;
+        }
+      }
+
+      // Preload all terms
+      $terms = taxonomy_term_load_multiple(array_keys($new_node_terms + $old_node_terms));
+      
+      // Compare between versions
+      $new_values = $old_values = array();
+      foreach ($terms as $term) {
+        // Term being in the new node but not in the old one
+        if (isset($new_node_terms[$term->tid]) && !isset($old_node_terms[$term->tid])) {
+          $old_values[] = '';
+          $new_values[] = $term->name;
+        }
+        // Term being in the old node but not in the new one
+        elseif (!isset($new_node_terms[$term->tid]) && isset($old_node_terms[$term->tid])) {
+          $old_values[] = $term->name;
+          $new_values[] = '';
+        }
+      }
+      // New terms autocreated
+      foreach ($new_terms as $term) {
+        $old_values[] = '';
+        $new_values[] = $term;
+      }
+
+      $result["{$field_name}"] = array(
+        '#name' => $instance['label'],
+        '#old' => $old_values,
+        '#new' => $new_values,
+      );
+    }
+  }
+  return $result;
+}
