diff --git a/README.md b/README.md
index a6fb495..f45458b 100644
--- a/README.md
+++ b/README.md
@@ -96,6 +96,13 @@ myEnv, err := godotenv.Read()
 s3Bucket := myEnv["S3_BUCKET"]
 ```
 
+... or from an `io.Reader` instead of a local file
+
+```go
+reader := getRemoteFile()
+myEnv, err := godotenv.Parse(reader)
+```
+
 ### Command Mode
 
 Assuming you've installed the command as above and you've got `$GOPATH/bin` in your `$PATH`
diff --git a/godotenv.go b/godotenv.go
index 0d9066c..f44a58d 100644
--- a/godotenv.go
+++ b/godotenv.go
@@ -16,6 +16,7 @@ package godotenv
 import (
 	"bufio"
 	"errors"
+	"io"
 	"os"
 	"os/exec"
 	"strings"
@@ -89,6 +90,34 @@ func Read(filenames ...string) (envMap map[string]string, err error) {
 	return
 }
 
+// Parse reads an env file from io.Reader, returning a map of keys and values.
+func Parse(r io.Reader) (envMap map[string]string, err error) {
+	envMap = make(map[string]string)
+
+	var lines []string
+	scanner := bufio.NewScanner(r)
+	for scanner.Scan() {
+		lines = append(lines, scanner.Text())
+	}
+
+	if err = scanner.Err(); err != nil {
+		return
+	}
+
+	for _, fullLine := range lines {
+		if !isIgnoredLine(fullLine) {
+			var key, value string
+			key, value, err = parseLine(fullLine)
+
+			if err != nil {
+				return
+			}
+			envMap[key] = value
+		}
+	}
+	return
+}
+
 // Exec loads env vars from the specified filenames (empty map falls back to default)
 // then executes the cmd specified.
 //
@@ -142,30 +171,7 @@ func readFile(filename string) (envMap map[string]string, err error) {
 	}
 	defer file.Close()
 
-	envMap = make(map[string]string)
-
-	var lines []string
-	scanner := bufio.NewScanner(file)
-	for scanner.Scan() {
-		lines = append(lines, scanner.Text())
-	}
-
-	if err = scanner.Err(); err != nil {
-		return
-	}
-
-	for _, fullLine := range lines {
-		if !isIgnoredLine(fullLine) {
-			var key, value string
-			key, value, err = parseLine(fullLine)
-
-			if err != nil {
-				return
-			}
-			envMap[key] = value
-		}
-	}
-	return
+	return Parse(file)
 }
 
 func parseLine(line string) (key string, value string, err error) {
diff --git a/godotenv_test.go b/godotenv_test.go
index a62bf87..2d46b19 100644
--- a/godotenv_test.go
+++ b/godotenv_test.go
@@ -1,6 +1,7 @@
 package godotenv
 
 import (
+	"bytes"
 	"os"
 	"testing"
 )
@@ -94,6 +95,23 @@ func TestReadPlainEnv(t *testing.T) {
 	}
 }
 
+func TestParse(t *testing.T) {
+	envMap, err := Parse(bytes.NewReader([]byte("ONE=1\nTWO='2'\nTHREE = \"3\"")))
+	expectedValues := map[string]string{
+		"ONE":   "1",
+		"TWO":   "2",
+		"THREE": "3",
+	}
+	if err != nil {
+		t.Fatalf("error parsing env: %v", err)
+	}
+	for key, value := range expectedValues {
+		if envMap[key] != value {
+			t.Errorf("expected %s to be %s, got %s", key, value, envMap[key])
+		}
+	}
+}
+
 func TestLoadDoesNotOverride(t *testing.T) {
 	envFileName := "fixtures/plain.env"