diff --git src/wp-includes/taxonomy.php src/wp-includes/taxonomy.php
index d942734..b65c624 100644
--- src/wp-includes/taxonomy.php
+++ src/wp-includes/taxonomy.php
@@ -640,7 +640,7 @@ class WP_Tax_Query {
 	 *		Possible values: 'term_id', 'slug', 'name', or 'term_taxonomy_id'
 	 *		Default: 'term_id'
 	 * - 'operator' string (optional)
-	 *		Possible values: 'AND', 'IN' or 'NOT IN'.
+	 *		Possible values: 'AND', 'IN', 'NOT IN', 'EXISTS', 'NOT EXISTS'
 	 *		Default: 'IN'
 	 * - 'include_children' bool (optional) Whether to include child terms. Requires that a taxonomy be specified.
 	 *		Default: true
@@ -798,6 +798,18 @@ class WP_Tax_Query {
 					WHERE term_taxonomy_id IN ($terms)
 					AND object_id = $primary_table.$primary_id_column
 				) = $num_terms";
+			} elseif ( 'NOT EXISTS' === $operator || 'EXISTS' === $operator ) {
+
+				$taxonomy = esc_sql( $query['taxonomy'] );
+
+				$where[] = "$operator (
+					SELECT 1
+					FROM $wpdb->term_relationships
+					INNER JOIN $wpdb->term_taxonomy
+					ON $wpdb->term_taxonomy.term_taxonomy_id = $wpdb->term_relationships.term_taxonomy_id
+					WHERE $wpdb->term_taxonomy.taxonomy = '$taxonomy'
+					AND $wpdb->term_relationships.object_id = $primary_table.$primary_id_column
+				)";
 			}
 
 			$i++;
diff --git tests/phpunit/tests/term/query.php tests/phpunit/tests/term/query.php
index 0a3c724..0e22b1f 100644
--- tests/phpunit/tests/term/query.php
+++ tests/phpunit/tests/term/query.php
@@ -231,4 +231,61 @@ class Tests_Tax_Query extends WP_UnitTestCase {
 		$q6 = get_posts( array( 'tag_slug__in' => array() ) );
 		$this->assertNotEmpty( $q6 );
 	}
+
+	public function test_operator_not_exists() {
+		$c1 = $this->factory->category->create();
+		$t1 = $this->factory->term->create( array( 'taxonomy' => 'post_tag', 'name' => 'foo' ) );
+		$t2 = $this->factory->term->create( array( 'taxonomy' => 'post_tag', 'name' => 'bar' ) );
+
+		$p1 = $this->factory->post->create();
+		$p2 = $this->factory->post->create();
+		$p3 = $this->factory->post->create();
+
+		wp_set_object_terms( $p1, array( $c1 ), 'category' );
+		wp_set_object_terms( $p2, array( $t1 ), 'post_tag' );
+		wp_set_object_terms( $p3, array( $t1 ), 'post_tag' );
+		wp_set_object_terms( $p3, array( $t2 ), 'post_tag' );
+
+		$found1 = $this->q->query( array(
+			'fields' => 'ids',
+			'orderby' => 'ID',
+			'order' => 'ASC',
+			'tax_query' => array(
+				array(
+					'taxonomy' => 'post_tag',
+					'operator' => 'NOT EXISTS',
+				),
+			),
+		) );
+
+		$this->assertSame( array( $p1 ), $found1 );
+	}
+
+	public function test_operator_exists() {
+		$c1 = $this->factory->category->create();
+		$t1 = $this->factory->term->create( array( 'taxonomy' => 'post_tag', 'name' => 'foo' ) );
+		$t2 = $this->factory->term->create( array( 'taxonomy' => 'post_tag', 'name' => 'bar' ) );
+		$p1 = $this->factory->post->create();
+		$p2 = $this->factory->post->create();
+		$p3 = $this->factory->post->create();
+
+		wp_set_object_terms( $p1, array( $c1 ), 'category' );
+		wp_set_object_terms( $p2, array( $t1 ), 'post_tag' );
+		wp_set_object_terms( $p3, array( $t1 ), 'post_tag' );
+		wp_set_object_terms( $p3, array( $t2 ), 'post_tag' );
+
+		$found1 = $this->q->query( array(
+			'fields' => 'ids',
+			'orderby' => 'ID',
+			'order' => 'ASC',
+			'tax_query' => array(
+				array(
+					'taxonomy' => 'post_tag',
+					'operator' => 'EXISTS',
+				),
+			),
+		) );
+
+		$this->assertSame( array( $p2, $p3 ), $found1 );
+	}
 }
