Index: wp-includes/meta.php
===================================================================
--- wp-includes/meta.php	(revision 19732)
+++ wp-includes/meta.php	(working copy)
@@ -724,6 +724,12 @@
 			$join[$i] .= $i ? " AS $alias" : '';
 			$join[$i] .= " ON ($primary_table.$primary_id_column = $alias.$meta_id_column)";
 
+			if( in_array( strtoupper( $q['compare'] ), array( 'EXISTS', 'NOT EXISTS' ) ) ) {
+				$join[$i]  = "INNER JOIN $meta_table";
+				$join[$i] .= $i ? " AS $alias" : '';
+				$join[$i] .= " ON ($primary_table.$primary_id_column = $alias.$meta_id_column AND $alias.meta_key = '$meta_key')";
+			}
+
 			$where[$k] = '';
 			if ( !empty( $meta_key ) )
 				$where[$k] = $wpdb->prepare( "$alias.meta_key = %s", $meta_key );
@@ -771,6 +777,10 @@
 				$where[$k] .= ' AND ';
 
 			$where[$k] = ' (' . $where[$k] . $wpdb->prepare( "CAST($alias.meta_value AS {$meta_type}) {$meta_compare} {$meta_compare_string})", $meta_value );
+
+			if( in_array( strtoupper( $q['compare'] ), array( 'EXISTS', 'NOT EXISTS' ) ) ) {
+				$where[$k] = ' (' . $alias.$meta_id_column . ' IS ' . ( ( strtoupper( $q['compare'] ) == 'EXISTS' ) ? 'NOT' : '' ) . ' NULL)';
+			}
 		}
 
 		$where = array_filter( $where );
