diff --git a/lib/spack/spack/__init__.py b/lib/spack/spack/__init__.py
index 50fe453cfb7530ad3cc3f8f66b38344ab3bcb9c6..bc24766510c68dc4b45780a8e87afe449d2838d4 100644
--- a/lib/spack/spack/__init__.py
+++ b/lib/spack/spack/__init__.py
@@ -59,6 +59,7 @@
 install_path   = join_path(prefix, "opt")
 share_path     = join_path(prefix, "share", "spack")
 dotkit_path    = join_path(share_path, "dotkit")
+tclmodule_path    = join_path(share_path, "tclmodule")
 
 #
 # Set up the packages database.
diff --git a/lib/spack/spack/cmd/load.py b/lib/spack/spack/cmd/load.py
new file mode 100644
index 0000000000000000000000000000000000000000..1389740df1590560ebe9694b6bb66b50ac480b1c
--- /dev/null
+++ b/lib/spack/spack/cmd/load.py
@@ -0,0 +1,50 @@
+##############################################################################
+# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Written by David Beckingsale, david@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://scalability-llnl.github.io/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License (as published by
+# the Free Software Foundation) version 2.1 dated February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+import argparse
+import llnl.util.tty as tty
+import spack
+
+description ="Add package to environment using module."
+
+def setup_parser(subparser):
+    subparser.add_argument(
+        'spec', nargs=argparse.REMAINDER, help='Spec of package to add.')
+
+
+def print_help():
+    tty.msg("Spack module support is not initialized.",
+            "",
+            "To use module with Spack, you must first run the command",
+            "below, which you can copy and paste:",
+            "",
+            "For bash:",
+            "    . %s/setup-env.bash" % spack.share_path,
+            "",
+            "ksh/csh/tcsh shells are currently unsupported",
+            "")
+
+
+def load(parser, args):
+    print_help()
diff --git a/lib/spack/spack/cmd/tclmodule.py b/lib/spack/spack/cmd/tclmodule.py
new file mode 100644
index 0000000000000000000000000000000000000000..da5c4f95fc4f73672fcc1de24fde8fff14343a70
--- /dev/null
+++ b/lib/spack/spack/cmd/tclmodule.py
@@ -0,0 +1,99 @@
+##############################################################################
+# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Written by David Beckingsale, david@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://scalability-llnl.github.io/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License (as published by
+# the Free Software Foundation) version 2.1 dated February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+import sys
+import os
+import shutil
+import argparse
+
+import llnl.util.tty as tty
+from llnl.util.lang import partition_list
+from llnl.util.filesystem import mkdirp
+
+import spack.cmd
+import spack.hooks.tclmodule
+from spack.spec import Spec
+
+
+description ="Find modules for packages if they exist."
+
+def setup_parser(subparser):
+    subparser.add_argument(
+        '--refresh', action='store_true', help='Regenerate all modules')
+
+    subparser.add_argument(
+        'spec', nargs=argparse.REMAINDER, help='spec to find a module for.')
+
+
+def module_find(parser, args):
+    if not args.spec:
+        parser.parse_args(['tclmodule', '-h'])
+
+    spec = spack.cmd.parse_specs(args.spec)
+    if len(spec) > 1:
+        tty.die("You can only pass one spec.")
+    spec = spec[0]
+
+    if not spack.db.exists(spec.name):
+        tty.die("No such package: %s" % spec.name)
+
+    specs = [s for s in spack.db.installed_package_specs() if s.satisfies(spec)]
+
+    if len(specs) == 0:
+        tty.die("No installed packages match spec %s" % spec)
+
+    if len(specs) > 1:
+        tty.error("Multiple matches for spec %s.  Choose one:" % spec)
+        for s in specs:
+            sys.stderr.write(s.tree(color=True))
+        sys.exit(1)
+
+    match = specs[0]
+    if not os.path.isfile(spack.hooks.tclmodules.tclmodules_file(match.package)):
+        tty.die("No module is installed for package %s." % spec)
+
+    print match.format('$_$@$+$%@$=$#')
+
+
+def module_refresh(parser, args):
+    query_specs = spack.cmd.parse_specs(args.spec)
+
+    specs = spack.db.installed_package_specs()
+    if query_specs:
+        specs = [s for s in specs
+                 if any(s.satisfies(q) for q in query_specs)]
+    else:
+        shutil.rmtree(spack.module_path, ignore_errors=False)
+        mkdirp(spack.module_path)
+
+    for spec in specs:
+        spack.hooks.tclmodule.post_install(spec.package)
+
+
+
+def tclmodule(parser, args):
+    if args.refresh:
+        module_refresh(parser, args)
+    else:
+        module_find(parser, args)
diff --git a/lib/spack/spack/cmd/unload.py b/lib/spack/spack/cmd/unload.py
new file mode 100644
index 0000000000000000000000000000000000000000..df009c840b3ec2900ee0ed41e674dd707a90e45e
--- /dev/null
+++ b/lib/spack/spack/cmd/unload.py
@@ -0,0 +1,36 @@
+##############################################################################
+# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Written by David Beckingsale, david@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://scalability-llnl.github.io/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License (as published by
+# the Free Software Foundation) version 2.1 dated February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+import argparse
+import spack.cmd.tclmodule
+
+description ="Remove package from environment using module."
+
+def setup_parser(subparser):
+    subparser.add_argument(
+        'spec', nargs=argparse.REMAINDER, help='Spec of package to remove.')
+
+
+def unload(parser, args):
+    spack.cmd.load.print_help()
diff --git a/lib/spack/spack/hooks/tclmodule.py b/lib/spack/spack/hooks/tclmodule.py
new file mode 100644
index 0000000000000000000000000000000000000000..7df41e267c7bea18ccaace86b2055487d53d5034
--- /dev/null
+++ b/lib/spack/spack/hooks/tclmodule.py
@@ -0,0 +1,85 @@
+##############################################################################
+# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Written by David Beckingsale, david@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://scalability-llnl.github.io/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License (as published by
+# the Free Software Foundation) version 2.1 dated February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+import os
+import re
+import textwrap
+import shutil
+from contextlib import closing
+
+from llnl.util.filesystem import join_path, mkdirp
+
+import spack
+
+
+def module_file(pkg):
+    m_file_name = pkg.spec.format('$_$@$%@$+$=$#')
+    return join_path(spack.module_path, m_file_name)
+
+
+def post_install(pkg):
+    if not os.path.exists(spack.module_path):
+        mkdirp(spack.module_path)
+
+    alterations = []
+    for var, path in [
+        ('PATH', pkg.prefix.bin),
+        ('MANPATH', pkg.prefix.man),
+        ('MANPATH', pkg.prefix.share_man),
+        ('LD_LIBRARY_PATH', pkg.prefix.lib),
+        ('LD_LIBRARY_PATH', pkg.prefix.lib64)]:
+
+        if os.path.isdir(path):
+            alterations.append("prepend_path %s %s\n" % (var, path))
+
+    if not alterations:
+        return
+
+    alterations.append("prepend_path CMAKE_PREFIX_PATH %s\n" % pkg.prefix)
+
+    m_file = module_file(pkg)
+    with closing(open(m_file, 'w')) as m:
+        # Put everything in the spack category.
+        m.write('#%Module1.0\n')
+
+        m.write('module-whatis \"%s\"\n' % pkg.spec.format("$_ $@"))
+
+        # Recycle the description
+        if pkg.__doc__:
+            m.write('proc ModulesHelp { } {\n')
+            doc = re.sub(r'\s+', ' ', pkg.__doc__)
+            m.write("puts str \"%s\"\n" % doc)
+            m.write('}')
+
+
+        # Write alterations
+        for alter in alterations:
+            m.write(alter)
+
+
+def post_uninstall(pkg):
+    m_file = module_file(pkg)
+    if os.path.exists(m_file):
+        shutil.rmtree(m_file, ignore_errors=True)
+
diff --git a/share/spack/setup-env.bash b/share/spack/setup-env.bash
index e22a259167257d5b152147f0298a9d1b08edc7cc..c23a5acab437905c352319bbdf9041dddf9ab1a2 100755
--- a/share/spack/setup-env.bash
+++ b/share/spack/setup-env.bash
@@ -65,8 +65,38 @@ function spack {
     # Filter out use and unuse.  For any other commands, just run the
     # command.
     case $_spack_subcommand in
-        "use") ;;
-        "unuse") ;;
+        "use"|"unuse")
+            # Shift any other args for use off before parsing spec.
+            _spack_use_args=""
+            if [[ "$1" =~ ^- ]]; then
+                _spack_use_args="$1"; shift
+                _spack_spec="$@"
+            fi
+
+            # Here the user has run use or unuse with a spec.  Find a matching
+            # spec with a dotkit using spack dotkit, then use or unuse the
+            # result.  If spack dotkit comes back with an error, do nothing.
+            if _spack_full_spec=$(command spack dotkit $_spack_spec); then
+                $_spack_subcommand $_spack_use_args $_spack_full_spec
+            fi
+            return
+            ;;
+        "load"|"unload")
+            # Shift any other args for module off before parsing spec.
+            _spack_module_args=""
+            if [[ "$1" =~ ^- ]]; then
+                _spack_module_args="$1"; shift
+                _spack_spec="$@"
+            fi
+
+            # Here the user has run use or unuse with a spec.  Find a matching
+            # spec with a dotkit using spack dotkit, then use or unuse the
+            # result.  If spack dotkit comes back with an error, do nothing.
+            if _spack_full_spec=$(command spack tclmodule $_spack_spec); then
+                $_spack_subcommand $_spack_module_args $_spack_full_spec
+            fi
+            return
+            ;;
         *)
             command spack $_spack_subcommand "$@"
             return
@@ -79,19 +109,6 @@ function spack {
         return
     fi
 
-    # Shift any other args for use off before parsing spec.
-    _spack_use_args=""
-    if [[ "$1" =~ ^- ]]; then
-        _spack_use_args="$1"; shift
-        _spack_spec="$@"
-    fi
-
-    # Here the user has run use or unuse with a spec.  Find a matching
-    # spec with a dotkit using spack dotkit, then use or unuse the
-    # result.  If spack dotkit comes back with an error, do nothing.
-    if _spack_full_spec=$(command spack dotkit $_spack_spec); then
-        $_spack_subcommand $_spack_use_args $_spack_full_spec
-    fi
 }
 
 ########################################################################
@@ -128,5 +145,5 @@ _spack_share_dir="$(dirname ${BASH_SOURCE[0]})"
 _spack_prefix="$(dirname $(dirname $_spack_share_dir))"
 
 _spack_pathadd DK_NODE "$_spack_share_dir/dotkit"
+_spack_pathadd MODULEPATH "$_spack_share_dir/modules"
 _spack_pathadd PATH    "$_spack_prefix/bin"
-