diff --git a/fixtures/substitutions.env b/fixtures/substitutions.env
new file mode 100644
index 0000000..44337a9
--- /dev/null
+++ b/fixtures/substitutions.env
@@ -0,0 +1,5 @@
+OPTION_A=1
+OPTION_B=${OPTION_A}
+OPTION_C=$OPTION_B
+OPTION_D=${OPTION_A}${OPTION_B}
+OPTION_E=${OPTION_NOT_DEFINED}
diff --git a/godotenv.go b/godotenv.go
index 48ae78c..19751d7 100644
--- a/godotenv.go
+++ b/godotenv.go
@@ -112,7 +112,7 @@ func Parse(r io.Reader) (envMap map[string]string, err error) {
 	for _, fullLine := range lines {
 		if !isIgnoredLine(fullLine) {
 			var key, value string
-			key, value, err = parseLine(fullLine)
+			key, value, err = parseLine(fullLine, envMap)
 
 			if err != nil {
 				return
@@ -209,7 +209,7 @@ func readFile(filename string) (envMap map[string]string, err error) {
 	return Parse(file)
 }
 
-func parseLine(line string) (key string, value string, err error) {
+func parseLine(line string, envMap map[string]string) (key string, value string, err error) {
 	if len(line) == 0 {
 		err = errors.New("zero length string")
 		return
@@ -259,11 +259,11 @@ func parseLine(line string) (key string, value string, err error) {
 	key = strings.Trim(key, " ")
 
 	// Parse the value
-	value = parseValue(splitString[1])
+	value = parseValue(splitString[1], envMap)
 	return
 }
 
-func parseValue(value string) string {
+func parseValue(value string, envMap map[string]string) string {
 
 	// trim
 	value = strings.Trim(value, " ")
@@ -291,6 +291,13 @@ func parseValue(value string) string {
 		}
 	}
 
+	// expand variables
+	value = os.Expand(value, func(key string) string {
+		if val, ok := envMap[key]; ok {
+			return val
+		}
+		return ""
+	})
 	return value
 }
 
diff --git a/godotenv_test.go b/godotenv_test.go
index fc4f7f0..bbbd658 100644
--- a/godotenv_test.go
+++ b/godotenv_test.go
@@ -11,7 +11,7 @@ import (
 var noopPresets = make(map[string]string)
 
 func parseAndCompare(t *testing.T, rawEnvLine string, expectedKey string, expectedValue string) {
-	key, value, _ := parseLine(rawEnvLine)
+	key, value, _ := parseLine(rawEnvLine, noopPresets)
 	if key != expectedKey || value != expectedValue {
 		t.Errorf("Expected '%v' to parse as '%v' => '%v', got '%v' => '%v' instead", rawEnvLine, expectedKey, expectedValue, key, value)
 	}
@@ -193,6 +193,19 @@ func TestLoadQuotedEnv(t *testing.T) {
 	loadEnvAndCompareValues(t, Load, envFileName, expectedValues, noopPresets)
 }
 
+func TestSubstituitions(t *testing.T) {
+	envFileName := "fixtures/substitutions.env"
+	expectedValues := map[string]string{
+		"OPTION_A": "1",
+		"OPTION_B": "1",
+		"OPTION_C": "1",
+		"OPTION_D": "11",
+		"OPTION_E": "",
+	}
+
+	loadEnvAndCompareValues(t, Load, envFileName, expectedValues, noopPresets)
+}
+
 func TestActualEnvVarsAreLeftAlone(t *testing.T) {
 	os.Clearenv()
 	os.Setenv("OPTION_A", "actualenv")
@@ -280,7 +293,7 @@ func TestParsing(t *testing.T) {
 	// it 'throws an error if line format is incorrect' do
 	// expect{env('lol$wut')}.to raise_error(Dotenv::FormatError)
 	badlyFormattedLine := "lol$wut"
-	_, _, err := parseLine(badlyFormattedLine)
+	_, _, err := parseLine(badlyFormattedLine, noopPresets)
 	if err == nil {
 		t.Errorf("Expected \"%v\" to return error, but it didn't", badlyFormattedLine)
 	}
@@ -348,7 +361,7 @@ func TestWrite(t *testing.T) {
 	//but single quotes are left alone
 	writeAndCompare(`key=va'lu'e`, `key="va'lu'e"`)
 	// newlines, backslashes, and some other special chars are escaped
-	writeAndCompare(`foo="$ba\n\r\\r!"`, `foo="\$ba\n\r\\r\!"`)
+	writeAndCompare(`foo="\n\r\\r!"`, `foo="\n\r\\r\!"`)
 	// lines should be sorted
 	writeAndCompare("foo=bar\nbaz=buzz", "baz=\"buzz\"\nfoo=\"bar\"")