diff --git wp-includes/query.php wp-includes/query.php
index f47a860a..e04682d 100644
--- wp-includes/query.php
+++ wp-includes/query.php
@@ -1699,10 +1699,14 @@ class WP_Query {
 		}
 
 		foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) {
-			if ( 'post_tag' == $taxonomy )
-				continue;	// Handled further down in the $q['tag'] block
-
-			if ( $t->query_var && !empty( $q[$t->query_var] ) ) {
+			if ( $t->query_var_id && !empty( $q[$t->query_var_id] ) ) {
+				$q[$t->query_var_id] = absint( $q[$t->query_var_id] );
+				$tax_query[] = array(
+					'taxonomy' => $taxonomy,
+					'terms' => $q[$t->query_var_id]
+				);
+			}
+			elseif ( 'post_tag' != $taxonomy && $t->query_var && !empty( $q[$t->query_var] ) ) {
 				$tax_query_defaults = array(
 					'taxonomy' => $taxonomy,
 					'field' => 'slug',
@@ -1803,14 +1807,6 @@ class WP_Query {
 			}
 		}
 
-		if ( !empty($q['tag_id']) ) {
-			$q['tag_id'] = absint( $q['tag_id'] );
-			$tax_query[] = array(
-				'taxonomy' => 'post_tag',
-				'terms' => $q['tag_id']
-			);
-		}
-
 		if ( !empty($q['tag__in']) ) {
 			$q['tag__in'] = array_map('absint', array_unique( (array) $q['tag__in'] ) );
 			$tax_query[] = array(
diff --git wp-includes/taxonomy.php wp-includes/taxonomy.php
index e231a6c..fc0ad9b 100644
--- wp-includes/taxonomy.php
+++ wp-includes/taxonomy.php
@@ -34,6 +34,7 @@ function create_initial_taxonomies() {
 	 	'hierarchical' => false,
 		'update_count_callback' => '_update_post_term_count',
 		'query_var' => 'tag',
+		'query_var_id' => 'tag_id',
 		'rewrite' => did_action( 'init' ) ? array(
 					'slug' => get_option('tag_base') ? get_option('tag_base') : 'tag',
 					'with_front' => ( get_option('tag_base') && ! $wp_rewrite->using_index_permalinks() ) ? false : true ) : false,
@@ -266,6 +267,8 @@ function is_taxonomy_hierarchical($taxonomy) {
  * query_var - false to prevent queries, or string to customize query var
  * (?$query_var=$term); default will use $taxonomy as query var.
  *
+ * query_var_id - string used to query terms by id, instead of by slug.
+ *
  * public - If the taxonomy should be publicly queryable; //@TODO not implemented.
  * defaults to true.
  *
@@ -301,6 +304,7 @@ function register_taxonomy( $taxonomy, $object_type, $args = array() ) {
 						'update_count_callback' => '',
 						'rewrite' => true,
 						'query_var' => $taxonomy,
+						'query_var_id' => false,
 						'public' => true,
 						'show_ui' => null,
 						'show_tagcloud' => null,
@@ -318,6 +322,11 @@ function register_taxonomy( $taxonomy, $object_type, $args = array() ) {
 		$wp->add_query_var($args['query_var']);
 	}
 
+	if ( false !== $args['query_var_id'] && !empty($wp) ) {
+		$args['query_var_id'] = sanitize_title_with_dashes($args['query_var_id']);
+		$wp->add_query_var($args['query_var_id']);
+	}
+
 	if ( false !== $args['rewrite'] && '' != get_option('permalink_structure') ) {
 		$args['rewrite'] = wp_parse_args($args['rewrite'], array(
 			'slug' => sanitize_title_with_dashes($taxonomy),
