diff --git a/src/execution/__tests__/variables-test.js b/src/execution/__tests__/variables-test.js
index 01b649766a..2011c86ea5 100644
--- a/src/execution/__tests__/variables-test.js
+++ b/src/execution/__tests__/variables-test.js
@@ -159,6 +159,36 @@ describe('Execute: Handles inputs', () => {
         });
       });
 
+      it('properly parses null value to null', async () => {
+        const doc = `
+        {
+          fieldWithObjectInput(input: {a: null, b: null, c: "C", d: null})
+        }
+        `;
+        const ast = parse(doc);
+
+        return expect(await execute(schema, ast)).to.deep.equal({
+          data: {
+            fieldWithObjectInput: '{"a":null,"b":null,"c":"C","d":null}'
+          }
+        });
+      });
+
+      it('properly parses null value in list', async () => {
+        const doc = `
+        {
+          fieldWithObjectInput(input: {b: ["A",null,"C"], c: "C"})
+        }
+        `;
+        const ast = parse(doc);
+
+        return expect(await execute(schema, ast)).to.deep.equal({
+          data: {
+            fieldWithObjectInput: '{"b":["A",null,"C"],"c":"C"}'
+          }
+        });
+      });
+
       it('does not use incorrect value', async () => {
         const doc = `
         {
diff --git a/src/execution/values.js b/src/execution/values.js
index ac678c7e5d..9f3abdf13e 100644
--- a/src/execution/values.js
+++ b/src/execution/values.js
@@ -13,6 +13,7 @@ import { forEach, isCollection } from 'iterall';
 import { GraphQLError } from '../error';
 import invariant from '../jsutils/invariant';
 import isNullish from '../jsutils/isNullish';
+import isInvalid from '../jsutils/isInvalid';
 import keyMap from '../jsutils/keyMap';
 import { typeFromAST } from '../utilities/typeFromAST';
 import { valueFromAST } from '../utilities/valueFromAST';
@@ -66,10 +67,10 @@ export function getArgumentValues(
     const name = argDef.name;
     const valueAST = argASTMap[name] ? argASTMap[name].value : null;
     let value = valueFromAST(valueAST, argDef.type, variableValues);
-    if (isNullish(value)) {
+    if (isInvalid(value)) {
       value = argDef.defaultValue;
     }
-    if (!isNullish(value)) {
+    if (!isInvalid(value)) {
       result[name] = value;
     }
     return result;
@@ -98,7 +99,7 @@ function getVariableValue(
   const inputType = ((type: any): GraphQLInputType);
   const errors = isValidJSValue(input, inputType);
   if (!errors.length) {
-    if (isNullish(input)) {
+    if (isInvalid(input)) {
       const defaultValue = definitionAST.defaultValue;
       if (defaultValue) {
         return valueFromAST(defaultValue, inputType);
@@ -134,10 +135,14 @@ function coerceValue(type: GraphQLInputType, value: mixed): mixed {
     return coerceValue(type.ofType, _value);
   }
 
-  if (isNullish(_value)) {
+  if (_value === null) {
     return null;
   }
 
+  if (isInvalid(_value)) {
+    return undefined;
+  }
+
   if (type instanceof GraphQLList) {
     const itemType = type.ofType;
     if (isCollection(_value)) {
@@ -158,10 +163,10 @@ function coerceValue(type: GraphQLInputType, value: mixed): mixed {
     return Object.keys(fields).reduce((obj, fieldName) => {
       const field = fields[fieldName];
       let fieldValue = coerceValue(field.type, _value[fieldName]);
-      if (isNullish(fieldValue)) {
+      if (isInvalid(fieldValue)) {
         fieldValue = field.defaultValue;
       }
-      if (!isNullish(fieldValue)) {
+      if (!isInvalid(fieldValue)) {
         obj[fieldName] = fieldValue;
       }
       return obj;
diff --git a/src/jsutils/isInvalid.js b/src/jsutils/isInvalid.js
new file mode 100644
index 0000000000..e226abb6e0
--- /dev/null
+++ b/src/jsutils/isInvalid.js
@@ -0,0 +1,16 @@
+/* @flow */
+/**
+ *  Copyright (c) 2015, Facebook, Inc.
+ *  All rights reserved.
+ *
+ *  This source code is licensed under the BSD-style license found in the
+ *  LICENSE file in the root directory of this source tree. An additional grant
+ *  of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+/**
+ * Returns true if a value is undefined, or NaN.
+ */
+export default function isInvalid(value: mixed): boolean {
+  return value === undefined || value !== value;
+}
diff --git a/src/language/__tests__/kitchen-sink.graphql b/src/language/__tests__/kitchen-sink.graphql
index 0e04e2e42d..993de9ad02 100644
--- a/src/language/__tests__/kitchen-sink.graphql
+++ b/src/language/__tests__/kitchen-sink.graphql
@@ -52,6 +52,6 @@ fragment frag on Friend {
 }
 
 {
-  unnamed(truthy: true, falsey: false),
+  unnamed(truthy: true, falsey: false, nullish: null),
   query
 }
diff --git a/src/language/__tests__/parser-test.js b/src/language/__tests__/parser-test.js
index a26e7b9033..bb425812b8 100644
--- a/src/language/__tests__/parser-test.js
+++ b/src/language/__tests__/parser-test.js
@@ -91,12 +91,6 @@ fragment MissingOn Type
     ).to.throw('Syntax Error GraphQL (1:9) Expected Name, found }');
   });
 
-  it('does not allow null as value', async () => {
-    expect(
-      () => parse('{ fieldWithNullableStringInput(input: null) }')
-    ).to.throw('Syntax Error GraphQL (1:39) Unexpected Name "null"');
-  });
-
   it('parses multi-byte characters', async () => {
     // Note: \u0A0A could be naively interpretted as two line-feed chars.
     expect(
@@ -296,6 +290,13 @@ fragment ${fragmentName} on Type {
 
   describe('parseValue', () => {
 
+    it('parses null value', () => {
+      expect(parseValue('null')).to.containSubset({
+        kind: Kind.NULL,
+        loc: { start: 0, end: 4 }
+      });
+    });
+
     it('parses list values', () => {
       expect(parseValue('[123 "abc"]')).to.containSubset({
         kind: Kind.LIST,
diff --git a/src/language/__tests__/printer-test.js b/src/language/__tests__/printer-test.js
index 51b93ab2aa..25b9920739 100644
--- a/src/language/__tests__/printer-test.js
+++ b/src/language/__tests__/printer-test.js
@@ -132,7 +132,7 @@ fragment frag on Friend {
 }
 
 {
-  unnamed(truthy: true, falsey: false)
+  unnamed(truthy: true, falsey: false, nullish: null)
   query
 }
 `);
diff --git a/src/language/__tests__/schema-kitchen-sink.graphql b/src/language/__tests__/schema-kitchen-sink.graphql
index d148276253..a56c0e4cc6 100644
--- a/src/language/__tests__/schema-kitchen-sink.graphql
+++ b/src/language/__tests__/schema-kitchen-sink.graphql
@@ -17,6 +17,7 @@ type Foo implements Bar {
   four(argument: String = "string"): String
   five(argument: [String] = ["string", "string"]): String
   six(argument: InputType = {key: "value"}): Type
+  seven(argument: Int = null): Type
 }
 
 type AnnotatedObject @onObject(arg: "value") {
diff --git a/src/language/__tests__/schema-printer-test.js b/src/language/__tests__/schema-printer-test.js
index 29376f32c9..4fa56275bb 100644
--- a/src/language/__tests__/schema-printer-test.js
+++ b/src/language/__tests__/schema-printer-test.js
@@ -63,6 +63,7 @@ type Foo implements Bar {
   four(argument: String = "string"): String
   five(argument: [String] = ["string", "string"]): String
   six(argument: InputType = {key: "value"}): Type
+  seven(argument: Int = null): Type
 }
 
 type AnnotatedObject @onObject(arg: "value") {
diff --git a/src/language/__tests__/visitor-test.js b/src/language/__tests__/visitor-test.js
index 3c3b6ca0ad..3a43936db0 100644
--- a/src/language/__tests__/visitor-test.js
+++ b/src/language/__tests__/visitor-test.js
@@ -614,6 +614,12 @@ describe('Visitor', () => {
       [ 'enter', 'BooleanValue', 'value', 'Argument' ],
       [ 'leave', 'BooleanValue', 'value', 'Argument' ],
       [ 'leave', 'Argument', 1, undefined ],
+      [ 'enter', 'Argument', 2, undefined ],
+      [ 'enter', 'Name', 'name', 'Argument' ],
+      [ 'leave', 'Name', 'name', 'Argument' ],
+      [ 'enter', 'NullValue', 'value', 'Argument' ],
+      [ 'leave', 'NullValue', 'value', 'Argument' ],
+      [ 'leave', 'Argument', 2, undefined ],
       [ 'leave', 'Field', 0, undefined ],
       [ 'enter', 'Field', 1, undefined ],
       [ 'enter', 'Name', 'name', 'Field' ],
diff --git a/src/language/ast.js b/src/language/ast.js
index 7c3f4b3050..81d52ae87a 100644
--- a/src/language/ast.js
+++ b/src/language/ast.js
@@ -126,6 +126,7 @@ export type Node =
   | FloatValue
   | StringValue
   | BooleanValue
+  | NullValue
   | EnumValue
   | ListValue
   | ObjectValue
@@ -260,6 +261,7 @@ export type Value =
   | FloatValue
   | StringValue
   | BooleanValue
+  | NullValue
   | EnumValue
   | ListValue
   | ObjectValue;
@@ -288,6 +290,11 @@ export type BooleanValue = {
   value: boolean;
 };
 
+export type NullValue = {
+  kind: 'NullValue';
+  loc?: Location;
+};
+
 export type EnumValue = {
   kind: 'EnumValue';
   loc?: Location;
diff --git a/src/language/kinds.js b/src/language/kinds.js
index 3b69f086de..774fc1606d 100644
--- a/src/language/kinds.js
+++ b/src/language/kinds.js
@@ -34,6 +34,7 @@ export const INT = 'IntValue';
 export const FLOAT = 'FloatValue';
 export const STRING = 'StringValue';
 export const BOOLEAN = 'BooleanValue';
+export const NULL = 'NullValue';
 export const ENUM = 'EnumValue';
 export const LIST = 'ListValue';
 export const OBJECT = 'ObjectValue';
diff --git a/src/language/parser.js b/src/language/parser.js
index 431529dcc6..af4ee1c715 100644
--- a/src/language/parser.js
+++ b/src/language/parser.js
@@ -89,6 +89,7 @@ import {
   FLOAT,
   STRING,
   BOOLEAN,
+  NULL,
   ENUM,
   LIST,
   OBJECT,
@@ -503,12 +504,15 @@ function parseFragmentName(lexer: Lexer<*>): Name {
  *   - FloatValue
  *   - StringValue
  *   - BooleanValue
+ *   - NullValue
  *   - EnumValue
  *   - ListValue[?Const]
  *   - ObjectValue[?Const]
  *
  * BooleanValue : one of `true` `false`
  *
+ * NullValue : `null`
+ *
  * EnumValue : Name but not `true`, `false` or `null`
  */
 function parseValueLiteral(lexer: Lexer<*>, isConst: boolean): Value {
@@ -547,15 +551,19 @@ function parseValueLiteral(lexer: Lexer<*>, isConst: boolean): Value {
           value: token.value === 'true',
           loc: loc(lexer, token)
         };
-      } else if (token.value !== 'null') {
+      } else if (token.value === 'null') {
         lexer.advance();
         return {
-          kind: (ENUM: 'EnumValue'),
-          value: ((token.value: any): string),
+          kind: (NULL: 'NullValue'),
           loc: loc(lexer, token)
         };
       }
-      break;
+      lexer.advance();
+      return {
+        kind: (ENUM: 'EnumValue'),
+        value: ((token.value: any): string),
+        loc: loc(lexer, token)
+      };
     case TokenKind.DOLLAR:
       if (!isConst) {
         return parseVariable(lexer);
diff --git a/src/language/printer.js b/src/language/printer.js
index b908162f1f..e056ce0e9f 100644
--- a/src/language/printer.js
+++ b/src/language/printer.js
@@ -76,6 +76,7 @@ const printDocASTReducer = {
   FloatValue: ({ value }) => value,
   StringValue: ({ value }) => JSON.stringify(value),
   BooleanValue: ({ value }) => JSON.stringify(value),
+  NullValue: () => 'null',
   EnumValue: ({ value }) => value,
   ListValue: ({ values }) => '[' + join(values, ', ') + ']',
   ObjectValue: ({ fields }) => '{' + join(fields, ', ') + '}',
diff --git a/src/language/visitor.js b/src/language/visitor.js
index 480c48a9c0..a8422170dd 100644
--- a/src/language/visitor.js
+++ b/src/language/visitor.js
@@ -27,6 +27,7 @@ export const QueryDocumentKeys = {
   FloatValue: [],
   StringValue: [],
   BooleanValue: [],
+  NullValue: [],
   EnumValue: [],
   ListValue: [ 'values' ],
   ObjectValue: [ 'fields' ],
diff --git a/src/type/definition.js b/src/type/definition.js
index dd62e7133a..6f77f6ea08 100644
--- a/src/type/definition.js
+++ b/src/type/definition.js
@@ -446,7 +446,7 @@ function defineFieldMap(
           name: argName,
           description: arg.description === undefined ? null : arg.description,
           type: arg.type,
-          defaultValue: arg.defaultValue === undefined ? null : arg.defaultValue
+          defaultValue: arg.defaultValue
         };
       });
     }
diff --git a/src/type/directives.js b/src/type/directives.js
index 0b1c30194d..cd8a39a2c8 100644
--- a/src/type/directives.js
+++ b/src/type/directives.js
@@ -84,7 +84,7 @@ export class GraphQLDirective {
           name: argName,
           description: arg.description === undefined ? null : arg.description,
           type: arg.type,
-          defaultValue: arg.defaultValue === undefined ? null : arg.defaultValue
+          defaultValue: arg.defaultValue
         };
       });
     }
diff --git a/src/utilities/__tests__/astFromValue-test.js b/src/utilities/__tests__/astFromValue-test.js
index a1491a7af9..6e1543b202 100644
--- a/src/utilities/__tests__/astFromValue-test.js
+++ b/src/utilities/__tests__/astFromValue-test.js
@@ -19,6 +19,7 @@ import {
   GraphQLString,
   GraphQLBoolean,
   GraphQLID,
+  GraphQLNonNull,
 } from '../../type';
 
 
@@ -33,10 +34,14 @@ describe('astFromValue', () => {
       { kind: 'BooleanValue', value: false }
     );
 
-    expect(astFromValue(null, GraphQLBoolean)).to.deep.equal(
+    expect(astFromValue(undefined, GraphQLBoolean)).to.deep.equal(
       null
     );
 
+    expect(astFromValue(null, GraphQLBoolean)).to.deep.equal(
+      { kind: 'NullValue' }
+    );
+
     expect(astFromValue(0, GraphQLBoolean)).to.deep.equal(
       { kind: 'BooleanValue', value: false }
     );
@@ -44,6 +49,11 @@ describe('astFromValue', () => {
     expect(astFromValue(1, GraphQLBoolean)).to.deep.equal(
       { kind: 'BooleanValue', value: true }
     );
+
+    const NonNullBoolean = new GraphQLNonNull(GraphQLBoolean);
+    expect(astFromValue(0, NonNullBoolean)).to.deep.equal(
+      { kind: 'BooleanValue', value: false }
+    );
   });
 
   it('converts Int values to Int ASTs', () => {
@@ -105,6 +115,10 @@ describe('astFromValue', () => {
     );
 
     expect(astFromValue(null, GraphQLString)).to.deep.equal(
+      { kind: 'NullValue' }
+    );
+
+    expect(astFromValue(undefined, GraphQLString)).to.deep.equal(
       null
     );
   });
@@ -133,6 +147,17 @@ describe('astFromValue', () => {
     );
 
     expect(astFromValue(null, GraphQLID)).to.deep.equal(
+      { kind: 'NullValue' }
+    );
+
+    expect(astFromValue(undefined, GraphQLID)).to.deep.equal(
+      null
+    );
+  });
+
+  it('does not converts NonNull values to NullValue', () => {
+    const NonNullBoolean = new GraphQLNonNull(GraphQLBoolean);
+    expect(astFromValue(null, NonNullBoolean)).to.deep.equal(
       null
     );
   });
@@ -220,4 +245,26 @@ describe('astFromValue', () => {
             value: { kind: 'EnumValue', value: 'HELLO' } } ] }
     );
   });
+
+  it('converts input objects with explicit nulls', () => {
+    const inputObj = new GraphQLInputObjectType({
+      name: 'MyInputObj',
+      fields: {
+        foo: { type: GraphQLFloat },
+        bar: { type: myEnum },
+      }
+    });
+
+    expect(astFromValue(
+      { foo: null },
+      inputObj
+    )).to.deep.equal(
+      { kind: 'ObjectValue',
+        fields: [
+          { kind: 'ObjectField',
+            name: { kind: 'Name', value: 'foo' },
+            value: { kind: 'NullValue' } } ] }
+    );
+  });
+
 });
diff --git a/src/utilities/__tests__/schemaPrinter-test.js b/src/utilities/__tests__/schemaPrinter-test.js
index 721f212bca..d25580c645 100644
--- a/src/utilities/__tests__/schemaPrinter-test.js
+++ b/src/utilities/__tests__/schemaPrinter-test.js
@@ -213,6 +213,25 @@ type Root {
     );
   });
 
+  it('Prints String Field With Int Arg With Default Null', () => {
+    const output = printSingleFieldSchema(
+      {
+        type: GraphQLString,
+        args: { argOne: { type: GraphQLInt, defaultValue: null } },
+      }
+    );
+    expect(output).to.equal(`
+schema {
+  query: Root
+}
+
+type Root {
+  singleField(argOne: Int = null): String
+}
+`
+    );
+  });
+
   it('Prints String Field With Int! Arg', () => {
     const output = printSingleFieldSchema(
       {
diff --git a/src/utilities/astFromValue.js b/src/utilities/astFromValue.js
index 0b7fae2fd9..b3aa2d98d1 100644
--- a/src/utilities/astFromValue.js
+++ b/src/utilities/astFromValue.js
@@ -12,12 +12,14 @@ import { forEach, isCollection } from 'iterall';
 
 import invariant from '../jsutils/invariant';
 import isNullish from '../jsutils/isNullish';
+import isInvalid from '../jsutils/isInvalid';
 import type {
   Value,
   IntValue,
   FloatValue,
   StringValue,
   BooleanValue,
+  NullValue,
   EnumValue,
   ListValue,
   ObjectValue,
@@ -28,6 +30,7 @@ import {
   FLOAT,
   STRING,
   BOOLEAN,
+  NULL,
   ENUM,
   LIST,
   OBJECT,
@@ -58,6 +61,7 @@ import { GraphQLID } from '../type/scalars';
  * | String        | String / Enum Value  |
  * | Number        | Int / Float          |
  * | Mixed         | Enum Value           |
+ * | null          | NullValue            |
  *
  */
 export function astFromValue(
@@ -68,12 +72,20 @@ export function astFromValue(
   const _value = value;
 
   if (type instanceof GraphQLNonNull) {
-    // Note: we're not checking that the result is non-null.
-    // This function is not responsible for validating the input value.
-    return astFromValue(_value, type.ofType);
+    const astValue = astFromValue(_value, type.ofType);
+    if (astValue && astValue.kind === NULL) {
+      return null;
+    }
+    return astValue;
+  }
+
+  // only explicit null, not undefined, NaN
+  if (_value === null) {
+    return ({ kind: NULL }: NullValue);
   }
 
-  if (isNullish(_value)) {
+  // undefined, NaN
+  if (isInvalid(_value)) {
     return null;
   }
 
diff --git a/src/utilities/isValidLiteralValue.js b/src/utilities/isValidLiteralValue.js
index 694872efee..96a74baaec 100644
--- a/src/utilities/isValidLiteralValue.js
+++ b/src/utilities/isValidLiteralValue.js
@@ -11,6 +11,7 @@
 import { print } from '../language/printer';
 import type { Value, ListValue, ObjectValue } from '../language/ast';
 import {
+  NULL,
   VARIABLE,
   LIST,
   OBJECT
@@ -41,7 +42,7 @@ export function isValidLiteralValue(
 ): Array<string> {
   // A value must be provided if the type is non-null.
   if (type instanceof GraphQLNonNull) {
-    if (!valueAST) {
+    if (!valueAST || (valueAST.kind === NULL)) {
       if (type.ofType.name) {
         return [ `Expected "${String(type.ofType.name)}!", found null.` ];
       }
@@ -50,7 +51,7 @@ export function isValidLiteralValue(
     return isValidLiteralValue(type.ofType, valueAST);
   }
 
-  if (!valueAST) {
+  if (!valueAST || (valueAST.kind === NULL)) {
     return [];
   }
 
diff --git a/src/utilities/schemaPrinter.js b/src/utilities/schemaPrinter.js
index fc0976603d..b01df5529c 100644
--- a/src/utilities/schemaPrinter.js
+++ b/src/utilities/schemaPrinter.js
@@ -10,6 +10,7 @@
 
 import invariant from '../jsutils/invariant';
 import isNullish from '../jsutils/isNullish';
+import isInvalid from '../jsutils/isInvalid';
 import { astFromValue } from '../utilities/astFromValue';
 import { print } from '../language/printer';
 import type { GraphQLSchema } from '../type/schema';
@@ -231,7 +232,7 @@ function printArgs(args, indentation = '') {
 
 function printInputValue(arg) {
   let argDecl = arg.name + ': ' + String(arg.type);
-  if (!isNullish(arg.defaultValue)) {
+  if (!isInvalid(arg.defaultValue)) {
     argDecl += ` = ${print(astFromValue(arg.defaultValue, arg.type))}`;
   }
   return argDecl;
diff --git a/src/utilities/valueFromAST.js b/src/utilities/valueFromAST.js
index 884d773af9..3d216a30da 100644
--- a/src/utilities/valueFromAST.js
+++ b/src/utilities/valueFromAST.js
@@ -11,6 +11,7 @@
 import keyMap from '../jsutils/keyMap';
 import invariant from '../jsutils/invariant';
 import isNullish from '../jsutils/isNullish';
+import isInvalid from '../jsutils/isInvalid';
 import * as Kind from '../language/kinds';
 import {
   GraphQLScalarType,
@@ -42,6 +43,7 @@ import type {
  * | String               | String        |
  * | Int / Float          | Number        |
  * | Enum Value           | Mixed         |
+ * | NullValue            | null          |
  *
  */
 export function valueFromAST(
@@ -57,13 +59,21 @@ export function valueFromAST(
   }
 
   if (!valueAST) {
+    // When there is no AST, then there is also no value.
+    // Importantly, this is different from returning the value null.
+    return;
+  }
+
+  if (valueAST.kind === Kind.NULL) {
+    // This is explicitly returning the value null.
     return null;
   }
 
   if (valueAST.kind === Kind.VARIABLE) {
     const variableName = (valueAST: Variable).name.value;
     if (!variables || !variables.hasOwnProperty(variableName)) {
-      return null;
+      // No valid return value.
+      return;
     }
     // Note: we're not doing any checking that this variable is correct. We're
     // assuming that this query has been validated and the variable usage here
@@ -83,7 +93,8 @@ export function valueFromAST(
 
   if (type instanceof GraphQLInputObjectType) {
     if (valueAST.kind !== Kind.OBJECT) {
-      return null;
+      // No valid return value.
+      return;
     }
     const fields = type.getFields();
     const fieldASTs = keyMap(
@@ -93,14 +104,11 @@ export function valueFromAST(
     return Object.keys(fields).reduce((obj, fieldName) => {
       const field = fields[fieldName];
       const fieldAST = fieldASTs[fieldName];
-      let fieldValue =
+      const fieldValue =
         valueFromAST(fieldAST && fieldAST.value, field.type, variables);
-      if (isNullish(fieldValue)) {
-        fieldValue = field.defaultValue;
-      }
-      if (!isNullish(fieldValue)) {
-        obj[fieldName] = fieldValue;
-      }
+
+      // If no valid field value was provided, use the default value
+      obj[fieldName] = isInvalid(fieldValue) ? field.defaultValue : fieldValue;
       return obj;
     }, {});
   }
diff --git a/src/validation/__tests__/ArgumentsOfCorrectType-test.js b/src/validation/__tests__/ArgumentsOfCorrectType-test.js
index 036dc8d921..3636c63683 100644
--- a/src/validation/__tests__/ArgumentsOfCorrectType-test.js
+++ b/src/validation/__tests__/ArgumentsOfCorrectType-test.js
@@ -115,6 +115,24 @@ describe('Validate: Argument values of correct type', () => {
       `);
     });
 
+    it('null into nullable type', () => {
+      expectPassesRule(ArgumentsOfCorrectType, `
+        {
+          complicatedArgs {
+            intArgField(intArg: null)
+          }
+        }
+      `);
+
+      expectPassesRule(ArgumentsOfCorrectType, `
+        {
+          dog(a: null, b: null, c:{ requiredField: true, intField: null }) {
+            name
+          }
+        }
+      `);
+    });
+
   });
 
 
@@ -454,7 +472,7 @@ describe('Validate: Argument values of correct type', () => {
       expectPassesRule(ArgumentsOfCorrectType, `
         {
           complicatedArgs {
-            stringListArgField(stringListArg: ["one", "two"])
+            stringListArgField(stringListArg: ["one", null, "two"])
           }
         }
       `);
@@ -470,6 +488,16 @@ describe('Validate: Argument values of correct type', () => {
       `);
     });
 
+    it('Null value', () => {
+      expectPassesRule(ArgumentsOfCorrectType, `
+        {
+          complicatedArgs {
+            stringListArgField(stringListArg: null)
+          }
+        }
+      `);
+    });
+
     it('Single value into List', () => {
       expectPassesRule(ArgumentsOfCorrectType, `
         {
@@ -646,6 +674,20 @@ describe('Validate: Argument values of correct type', () => {
       ]);
     });
 
+    it('Null value', () => {
+      expectFailsRule(ArgumentsOfCorrectType, `
+        {
+          complicatedArgs {
+            multipleReqs(req1: null)
+          }
+        }
+      `, [
+        badValue('req1', 'Int!', 'null', 4, 32, [
+          'Expected "Int!", found null.'
+        ]),
+      ]);
+    });
+
   });
 
 
diff --git a/src/validation/__tests__/DefaultValuesOfCorrectType-test.js b/src/validation/__tests__/DefaultValuesOfCorrectType-test.js
index ecbe313ae6..e9872d172d 100644
--- a/src/validation/__tests__/DefaultValuesOfCorrectType-test.js
+++ b/src/validation/__tests__/DefaultValuesOfCorrectType-test.js
@@ -68,6 +68,44 @@ describe('Validate: Variable default values of correct type', () => {
     `);
   });
 
+  it('variables with valid default null values', () => {
+    expectPassesRule(DefaultValuesOfCorrectType, `
+      query WithDefaultValues(
+        $a: Int = null,
+        $b: String = null,
+        $c: ComplexInput = { requiredField: true, intField: null }
+      ) {
+        dog { name }
+      }
+    `);
+  });
+
+  it('variables with invalid default null values', () => {
+    expectFailsRule(DefaultValuesOfCorrectType, `
+      query WithDefaultValues(
+        $a: Int! = null,
+        $b: String! = null,
+        $c: ComplexInput = { requiredField: null, intField: null }
+      ) {
+        dog { name }
+      }
+    `, [
+      defaultForNonNullArg('a', 'Int!', 'Int', 3, 20),
+      badValue('a', 'Int!', 'null', 3, 20, [
+        'Expected "Int!", found null.'
+      ]),
+      defaultForNonNullArg('b', 'String!', 'String', 4, 23),
+      badValue('b', 'String!', 'null', 4, 23, [
+        'Expected "String!", found null.'
+      ]),
+      badValue('c', 'ComplexInput', '{requiredField: null, intField: null}',
+        5, 28, [
+          'In field "requiredField": Expected "Boolean!", found null.'
+        ]
+      ),
+    ]);
+  });
+
   it('no required variables with default values', () => {
     expectFailsRule(DefaultValuesOfCorrectType, `
       query UnreachableDefaultValues($a: Int! = 3, $b: String! = "default") {