diff --git a/pkg/chartutil/testdata/albatross/values.toml b/pkg/chartutil/testdata/albatross/values.toml
deleted file mode 100644
index 0ef7eb2f9ade07538c2f24aa5318d40be52fd61c..0000000000000000000000000000000000000000
--- a/pkg/chartutil/testdata/albatross/values.toml
+++ /dev/null
@@ -1 +0,0 @@
-albatross = "true"
diff --git a/pkg/chartutil/testdata/albatross/values.yaml b/pkg/chartutil/testdata/albatross/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0acfa292fc34df135d20b07764bd7a21930a2bb7
--- /dev/null
+++ b/pkg/chartutil/testdata/albatross/values.yaml
@@ -0,0 +1 @@
+albatross: "true"
diff --git a/pkg/chartutil/testdata/coleridge.yaml b/pkg/chartutil/testdata/coleridge.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b6579628bd61d32f96d57b6e1f755272cd644e03
--- /dev/null
+++ b/pkg/chartutil/testdata/coleridge.yaml
@@ -0,0 +1,12 @@
+poet: "Coleridge"
+title: "Rime of the Ancient Mariner"
+stanza: ["at", "length", "did", "cross", "an", "Albatross"]
+
+mariner:
+  with: "crossbow"
+  shot: "ALBATROSS"
+
+water:
+  water:
+    where: "everywhere"
+    nor: "any drop to drink"
diff --git a/pkg/chartutil/testdata/frobnitz-1.2.3.tgz b/pkg/chartutil/testdata/frobnitz-1.2.3.tgz
index c908b22642d0aac2394809200e6baa2bc7600b21..80c0a25022b6306a4aadb290475650981f1fcef5 100644
Binary files a/pkg/chartutil/testdata/frobnitz-1.2.3.tgz and b/pkg/chartutil/testdata/frobnitz-1.2.3.tgz differ
diff --git a/pkg/chartutil/testdata/frobnitz/charts/alpine/charts/mast1/values.toml b/pkg/chartutil/testdata/frobnitz/charts/alpine/charts/mast1/values.yaml
similarity index 100%
rename from pkg/chartutil/testdata/frobnitz/charts/alpine/charts/mast1/values.toml
rename to pkg/chartutil/testdata/frobnitz/charts/alpine/charts/mast1/values.yaml
diff --git a/pkg/chartutil/testdata/frobnitz/charts/alpine/values.toml b/pkg/chartutil/testdata/frobnitz/charts/alpine/values.toml
deleted file mode 100644
index 504e6e1be90d2058eb107c5f21001d7a3ff4bcb6..0000000000000000000000000000000000000000
--- a/pkg/chartutil/testdata/frobnitz/charts/alpine/values.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-# The pod name
-name = "my-alpine"
diff --git a/pkg/chartutil/testdata/frobnitz/charts/alpine/values.yaml b/pkg/chartutil/testdata/frobnitz/charts/alpine/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6c2aab7ba9df3f92832ce2844b001108f84013d0
--- /dev/null
+++ b/pkg/chartutil/testdata/frobnitz/charts/alpine/values.yaml
@@ -0,0 +1,2 @@
+# The pod name
+name: "my-alpine"
diff --git a/pkg/chartutil/testdata/frobnitz/charts/mariner-4.3.2.tgz b/pkg/chartutil/testdata/frobnitz/charts/mariner-4.3.2.tgz
index d4f19e6243532eba705a306a0c7cca462aa41345..3b6f987b3b39b992636405c611bc710066b3a8cd 100644
Binary files a/pkg/chartutil/testdata/frobnitz/charts/mariner-4.3.2.tgz and b/pkg/chartutil/testdata/frobnitz/charts/mariner-4.3.2.tgz differ
diff --git a/pkg/chartutil/testdata/frobnitz/values.toml b/pkg/chartutil/testdata/frobnitz/values.toml
deleted file mode 100644
index 6fc24051fe1e277d63d7b5a8cd582cbb985d0cdd..0000000000000000000000000000000000000000
--- a/pkg/chartutil/testdata/frobnitz/values.toml
+++ /dev/null
@@ -1,6 +0,0 @@
-# A values file contains configuration.
-
-name = "Some Name"
-
-[section]
-name = "Name in a section"
diff --git a/pkg/chartutil/testdata/frobnitz/values.yaml b/pkg/chartutil/testdata/frobnitz/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..61f501258835165a881de21520fe570295a53241
--- /dev/null
+++ b/pkg/chartutil/testdata/frobnitz/values.yaml
@@ -0,0 +1,6 @@
+# A values file contains configuration.
+
+name: "Some Name"
+
+section:
+  name: "Name in a section"
diff --git a/pkg/chartutil/testdata/mariner/charts/albatross-0.1.0.tgz b/pkg/chartutil/testdata/mariner/charts/albatross-0.1.0.tgz
index ed3c1aee9d62a5860abd1069ed0d4863047e1ca7..6795b2d9e8d5ac0f91c5d842bb20f3ab82b42a0c 100644
Binary files a/pkg/chartutil/testdata/mariner/charts/albatross-0.1.0.tgz and b/pkg/chartutil/testdata/mariner/charts/albatross-0.1.0.tgz differ
diff --git a/pkg/chartutil/testdata/mariner/values.toml b/pkg/chartutil/testdata/mariner/values.yaml
similarity index 53%
rename from pkg/chartutil/testdata/mariner/values.toml
rename to pkg/chartutil/testdata/mariner/values.yaml
index 4a7bbf8e422c40c4d74fd22c368a27e44fb87cc9..e1609e243b76dbaff2316d372533111a0201dcea 100644
--- a/pkg/chartutil/testdata/mariner/values.toml
+++ b/pkg/chartutil/testdata/mariner/values.yaml
@@ -1,4 +1,4 @@
 # Default values for mariner.
-# This is a TOML-formatted file. https://github.com/toml-lang/toml
+# This is a YAML-formatted file. https://github.com/toml-lang/toml
 # Declare name/value pairs to be passed into your templates.
-# name = "value"
+# name: "value"
diff --git a/pkg/chartutil/values.go b/pkg/chartutil/values.go
new file mode 100644
index 0000000000000000000000000000000000000000..904b9f2de0d6a699b867c9c9ddea1a8844a24928
--- /dev/null
+++ b/pkg/chartutil/values.go
@@ -0,0 +1,81 @@
+package chartutil
+
+import (
+	"errors"
+	"io"
+	"io/ioutil"
+	"strings"
+
+	"github.com/ghodss/yaml"
+)
+
+// ErrNoTable indicates that a chart does not have a matching table.
+var ErrNoTable = errors.New("no table")
+
+// Values represents a collection of chart values.
+type Values map[string]interface{}
+
+// Table gets a table (YAML subsection) from a Values object.
+//
+// The table is returned as a Values.
+//
+// Compound table names may be specified with dots:
+//
+//	foo.bar
+//
+// The above will be evaluated as "The table bar inside the table
+// foo".
+//
+// An ErrNoTable is returned if the table does not exist.
+func (v Values) Table(name string) (Values, error) {
+	names := strings.Split(name, ".")
+	table := v
+	var err error
+
+	for _, n := range names {
+		table, err = tableLookup(table, n)
+		if err != nil {
+			return table, err
+		}
+	}
+	return table, err
+}
+
+// Encode writes serialized Values information to the given io.Writer.
+func (v Values) Encode(w io.Writer) error {
+	//return yaml.NewEncoder(w).Encode(v)
+	out, err := yaml.Marshal(v)
+	if err != nil {
+		return err
+	}
+	_, err = w.Write(out)
+	return err
+}
+
+func tableLookup(v Values, simple string) (Values, error) {
+	v2, ok := v[simple]
+	if !ok {
+		return v, ErrNoTable
+	}
+	vv, ok := v2.(map[string]interface{})
+	if !ok {
+		return vv, ErrNoTable
+	}
+	return vv, nil
+}
+
+// ReadValues will parse YAML byte data into a Values.
+func ReadValues(data []byte) (Values, error) {
+	out := map[string]interface{}{}
+	err := yaml.Unmarshal(data, &out)
+	return out, err
+}
+
+// ReadValuesFile will parse a YAML file into a Values.
+func ReadValuesFile(filename string) (Values, error) {
+	data, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return map[string]interface{}{}, err
+	}
+	return ReadValues(data)
+}
diff --git a/pkg/chartutil/values_test.go b/pkg/chartutil/values_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..6cf69e3f693b2b180a4eb7bda7024958de830f58
--- /dev/null
+++ b/pkg/chartutil/values_test.go
@@ -0,0 +1,141 @@
+package chartutil
+
+import (
+	"bytes"
+	"fmt"
+	"testing"
+	"text/template"
+)
+
+func TestReadValues(t *testing.T) {
+	doc := `# Test YAML parse
+poet: "Coleridge"
+title: "Rime of the Ancient Mariner"
+stanza:
+  - "at"
+  - "length"
+  - "did"
+  - cross
+  - an
+  - Albatross
+
+mariner:
+  with: "crossbow"
+  shot: "ALBATROSS"
+
+water:
+  water:
+    where: "everywhere"
+    nor: "any drop to drink"
+`
+
+	data, err := ReadValues([]byte(doc))
+	if err != nil {
+		t.Fatalf("Error parsing bytes: %s", err)
+	}
+	matchValues(t, data)
+}
+
+func TestReadValuesFile(t *testing.T) {
+	data, err := ReadValuesFile("./testdata/coleridge.yaml")
+	if err != nil {
+		t.Fatalf("Error reading YAML file: %s", err)
+	}
+	matchValues(t, data)
+}
+
+func ExampleValues() {
+	doc := `
+title: "Moby Dick"
+chapter:
+  one:
+    title: "Loomings"
+  two:
+    title: "The Carpet-Bag"
+  three:
+    title: "The Spouter Inn"
+`
+	d, err := ReadValues([]byte(doc))
+	if err != nil {
+		panic(err)
+	}
+	ch1, err := d.Table("chapter.one")
+	if err != nil {
+		panic("could not find chapter one")
+	}
+	fmt.Print(ch1["title"])
+	// Output:
+	// Loomings
+}
+
+func TestTable(t *testing.T) {
+	doc := `
+title: "Moby Dick"
+chapter:
+  one:
+    title: "Loomings"
+  two:
+    title: "The Carpet-Bag"
+  three:
+    title: "The Spouter Inn"
+`
+	d, err := ReadValues([]byte(doc))
+	if err != nil {
+		t.Fatalf("Failed to parse the White Whale: %s", err)
+	}
+
+	if _, err := d.Table("title"); err == nil {
+		t.Fatalf("Title is not a table.")
+	}
+
+	if _, err := d.Table("chapter"); err != nil {
+		t.Fatalf("Failed to get the chapter table: %s\n%v", err, d)
+	}
+
+	if v, err := d.Table("chapter.one"); err != nil {
+		t.Errorf("Failed to get chapter.one: %s", err)
+	} else if v["title"] != "Loomings" {
+		t.Errorf("Unexpected title: %s", v["title"])
+	}
+
+	if _, err := d.Table("chapter.three"); err != nil {
+		t.Errorf("Chapter three is missing: %s\n%v", err, d)
+	}
+
+	if _, err := d.Table("chapter.OneHundredThirtySix"); err == nil {
+		t.Errorf("I think you mean 'Epilogue'")
+	}
+}
+
+func matchValues(t *testing.T, data map[string]interface{}) {
+	if data["poet"] != "Coleridge" {
+		t.Errorf("Unexpected poet: %s", data["poet"])
+	}
+
+	if o, err := ttpl("{{len .stanza}}", data); err != nil {
+		t.Errorf("len stanza: %s", err)
+	} else if o != "6" {
+		t.Errorf("Expected 6, got %s", o)
+	}
+
+	if o, err := ttpl("{{.mariner.shot}}", data); err != nil {
+		t.Errorf(".mariner.shot: %s", err)
+	} else if o != "ALBATROSS" {
+		t.Errorf("Expected that mariner shot ALBATROSS")
+	}
+
+	if o, err := ttpl("{{.water.water.where}}", data); err != nil {
+		t.Errorf(".water.water.where: %s", err)
+	} else if o != "everywhere" {
+		t.Errorf("Expected water water everywhere")
+	}
+}
+
+func ttpl(tpl string, v map[string]interface{}) (string, error) {
+	var b bytes.Buffer
+	tt := template.Must(template.New("t").Parse(tpl))
+	if err := tt.Execute(&b, v); err != nil {
+		return "", err
+	}
+	return b.String(), nil
+}