diff --git a/core/src/main/scala/org/apache/spark/util/VersionUtils.scala b/core/src/main/scala/org/apache/spark/util/VersionUtils.scala
new file mode 100644
index 0000000000000000000000000000000000000000..828153b8684204948cb4eaee84331890fd9f86c1
--- /dev/null
+++ b/core/src/main/scala/org/apache/spark/util/VersionUtils.scala
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.spark.util
+
+/**
+ * Utilities for working with Spark version strings
+ */
+private[spark] object VersionUtils {
+
+  private val majorMinorRegex = """^(\d+)\.(\d+)(\..*)?$""".r
+
+  /**
+   * Given a Spark version string, return the major version number.
+   * E.g., for 2.0.1-SNAPSHOT, return 2.
+   */
+  def majorVersion(sparkVersion: String): Int = majorMinorVersion(sparkVersion)._1
+
+  /**
+   * Given a Spark version string, return the minor version number.
+   * E.g., for 2.0.1-SNAPSHOT, return 0.
+   */
+  def minorVersion(sparkVersion: String): Int = majorMinorVersion(sparkVersion)._2
+
+  /**
+   * Given a Spark version string, return the (major version number, minor version number).
+   * E.g., for 2.0.1-SNAPSHOT, return (2, 0).
+   */
+  def majorMinorVersion(sparkVersion: String): (Int, Int) = {
+    majorMinorRegex.findFirstMatchIn(sparkVersion) match {
+      case Some(m) =>
+        (m.group(1).toInt, m.group(2).toInt)
+      case None =>
+        throw new IllegalArgumentException(s"Spark tried to parse '$sparkVersion' as a Spark" +
+          s" version string, but it could not find the major and minor version numbers.")
+    }
+  }
+}
diff --git a/core/src/test/scala/org/apache/spark/util/VersionUtilsSuite.scala b/core/src/test/scala/org/apache/spark/util/VersionUtilsSuite.scala
new file mode 100644
index 0000000000000000000000000000000000000000..aaf79ebd4f9fcf0ba22b7df6fab968b3c9e89065
--- /dev/null
+++ b/core/src/test/scala/org/apache/spark/util/VersionUtilsSuite.scala
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.spark.util
+
+import org.apache.spark.SparkFunSuite
+
+class VersionUtilsSuite extends SparkFunSuite {
+
+  import org.apache.spark.util.VersionUtils._
+
+  test("Parse Spark major version") {
+    assert(majorVersion("2.0") === 2)
+    assert(majorVersion("12.10.11") === 12)
+    assert(majorVersion("2.0.1-SNAPSHOT") === 2)
+    assert(majorVersion("2.0.x") === 2)
+    withClue("majorVersion parsing should fail for invalid major version number") {
+      intercept[IllegalArgumentException] {
+        majorVersion("2z.0")
+      }
+    }
+    withClue("majorVersion parsing should fail for invalid minor version number") {
+      intercept[IllegalArgumentException] {
+        majorVersion("2.0z")
+      }
+    }
+  }
+
+  test("Parse Spark minor version") {
+    assert(minorVersion("2.0") === 0)
+    assert(minorVersion("12.10.11") === 10)
+    assert(minorVersion("2.0.1-SNAPSHOT") === 0)
+    assert(minorVersion("2.0.x") === 0)
+    withClue("minorVersion parsing should fail for invalid major version number") {
+      intercept[IllegalArgumentException] {
+        minorVersion("2z.0")
+      }
+    }
+    withClue("minorVersion parsing should fail for invalid minor version number") {
+      intercept[IllegalArgumentException] {
+        minorVersion("2.0z")
+      }
+    }
+  }
+
+  test("Parse Spark major and minor versions") {
+    assert(majorMinorVersion("2.0") === (2, 0))
+    assert(majorMinorVersion("12.10.11") === (12, 10))
+    assert(majorMinorVersion("2.0.1-SNAPSHOT") === (2, 0))
+    assert(majorMinorVersion("2.0.x") === (2, 0))
+    withClue("majorMinorVersion parsing should fail for invalid major version number") {
+      intercept[IllegalArgumentException] {
+        majorMinorVersion("2z.0")
+      }
+    }
+    withClue("majorMinorVersion parsing should fail for invalid minor version number") {
+      intercept[IllegalArgumentException] {
+        majorMinorVersion("2.0z")
+      }
+    }
+  }
+}