diff --git a/doc/release-notes.md b/doc/release-notes.md
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -3,3 +3,5 @@
   <https://download.bitcoinabc.org/0.18.7/>
 
 This release includes the following features and fixes:
+ - Add the `-walletdir` option to configure the directory in which the wallet
+   files are stored. If a relative path is used, it is relative to tha data dir.
diff --git a/src/Makefile.am b/src/Makefile.am
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -210,6 +210,7 @@
   wallet/rpcwallet.h \
   wallet/wallet.h \
   wallet/walletdb.h \
+  wallet/walletutil.h \
   warnings.h \
   zmq/zmqabstractnotifier.h \
   zmq/zmqconfig.h\
@@ -297,6 +298,7 @@
   wallet/rpcwallet.cpp \
   wallet/wallet.cpp \
   wallet/walletdb.cpp \
+  wallet/walletutil.cpp \
   $(BITCOIN_CORE_H)
 
 # crypto primitives library
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
@@ -19,6 +19,7 @@
 	rpcwallet.cpp
 	wallet.cpp
 	walletdb.cpp
+	walletutil.cpp
 )
 
 target_link_libraries(wallet util univalue Event ${BDBXX_LIBRARY})
diff --git a/src/wallet/db.h b/src/wallet/db.h
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -171,11 +171,11 @@
     static bool PeriodicFlush(CWalletDBWrapper &dbw);
     /* verifies the database environment */
     static bool VerifyEnvironment(const std::string &walletFile,
-                                  const fs::path &dataDir,
+                                  const fs::path &walletDir,
                                   std::string &errorStr);
     /* verifies the database file */
     static bool VerifyDatabaseFile(const std::string &walletFile,
-                                   const fs::path &dataDir,
+                                   const fs::path &walletDir,
                                    std::string &warningStr,
                                    std::string &errorStr,
                                    CDBEnv::recoverFunc_type recoverFunc);
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -11,6 +11,7 @@
 #include "protocol.h"
 #include "util.h"
 #include "utilstrencodings.h"
+#include "wallet/walletutil.h"
 
 #include <boost/thread.hpp>
 #include <boost/version.hpp>
@@ -265,22 +266,22 @@
 }
 
 bool CDB::VerifyEnvironment(const std::string &walletFile,
-                            const fs::path &dataDir, std::string &errorStr) {
+                            const fs::path &walletDir, std::string &errorStr) {
     LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
     LogPrintf("Using wallet %s\n", walletFile);
 
     // Wallet file must be a plain filename without a directory
     if (walletFile != fs::basename(walletFile) + fs::extension(walletFile)) {
-        errorStr = strprintf(_("Wallet %s resides outside data directory %s"),
-                             walletFile, dataDir.string());
+        errorStr = strprintf(_("Wallet %s resides outside wallet directory %s"),
+                             walletFile, walletDir.string());
         return false;
     }
 
-    if (!bitdb.Open(dataDir)) {
+    if (!bitdb.Open(walletDir)) {
         // try moving the database env out of the way
-        fs::path pathDatabase = dataDir / "database";
+        fs::path pathDatabase = walletDir / "database";
         fs::path pathDatabaseBak =
-            dataDir / strprintf("database.%d.bak", GetTime());
+            walletDir / strprintf("database.%d.bak", GetTime());
         try {
             fs::rename(pathDatabase, pathDatabaseBak);
             LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(),
@@ -291,12 +292,12 @@
         }
 
         // try again
-        if (!bitdb.Open(dataDir)) {
+        if (!bitdb.Open(walletDir)) {
             // if it still fails, it probably means we can't even create the
             // database env
             errorStr = strprintf(
                 _("Error initializing wallet database environment %s!"),
-                GetDataDir());
+                walletDir);
             return false;
         }
     }
@@ -304,10 +305,10 @@
 }
 
 bool CDB::VerifyDatabaseFile(const std::string &walletFile,
-                             const fs::path &dataDir, std::string &warningStr,
+                             const fs::path &walletDir, std::string &warningStr,
                              std::string &errorStr,
                              CDBEnv::recoverFunc_type recoverFunc) {
-    if (fs::exists(dataDir / walletFile)) {
+    if (fs::exists(walletDir / walletFile)) {
         std::string backup_filename;
         CDBEnv::VerifyResult r =
             bitdb.Verify(walletFile, recoverFunc, backup_filename);
@@ -317,7 +318,7 @@
                   " Original %s saved as %s in %s; if"
                   " your balance or transactions are incorrect you should"
                   " restore from a backup."),
-                walletFile, backup_filename, dataDir);
+                walletFile, backup_filename, walletDir);
         }
         if (r == CDBEnv::RECOVER_FAIL) {
             errorStr = strprintf(_("%s corrupt, salvage failed"), walletFile);
@@ -430,7 +431,7 @@
 
     {
         LOCK(env->cs_db);
-        if (!env->Open(GetDataDir())) {
+        if (!env->Open(GetWalletDir())) {
             throw std::runtime_error(
                 "CDB: Failed to open database environment.");
         }
@@ -743,7 +744,7 @@
                 env->mapFileUseCount.erase(strFile);
 
                 // Copy wallet file.
-                fs::path pathSrc = GetDataDir() / strFile;
+                fs::path pathSrc = GetWalletDir() / strFile;
                 fs::path pathDest(strDest);
                 if (fs::is_directory(pathDest)) {
                     pathDest /= strFile;
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -12,6 +12,7 @@
 #include "validation.h"
 #include "wallet/rpcwallet.h"
 #include "wallet/wallet.h"
+#include "wallet/walletutil.h"
 #include "walletinitinterface.h"
 
 class WalletInit : public WalletInitInterface {
@@ -102,6 +103,10 @@
         "-walletbroadcast",
         _("Make the wallet broadcast transactions") + " " +
             strprintf(_("(default: %d)"), DEFAULT_WALLETBROADCAST));
+    strUsage += HelpMessageOpt(
+        "-walletdir=<dir>",
+        _("Specify directory to hold wallets (default: <datadir>/wallets if it "
+          "exists, otherwise <datadir>)"));
     strUsage += HelpMessageOpt("-walletnotify=<cmd>",
                                _("Execute command when a wallet transaction "
                                  "changes (%s in cmd is replaced by TxID)"));
@@ -301,6 +306,14 @@
         return true;
     }
 
+    if (gArgs.IsArgSet("-walletdir") && !fs::is_directory(GetWalletDir())) {
+        return InitError(strprintf(
+            _("Error: Specified wallet directory \"%s\" does not exist."),
+            gArgs.GetArg("-walletdir", "").c_str()));
+    }
+
+    LogPrintf("Using wallet directory %s\n", GetWalletDir().string());
+
     uiInterface.InitMessage(_("Verifying wallet(s)..."));
 
     // Keep track of each wallet absolute path to detect duplicates.
@@ -320,7 +333,7 @@
                                        walletFile));
         }
 
-        fs::path wallet_path = fs::absolute(walletFile, GetDataDir());
+        fs::path wallet_path = fs::absolute(walletFile, GetWalletDir());
 
         if (fs::exists(wallet_path) && (!fs::is_regular_file(wallet_path) ||
                                         fs::is_symlink(wallet_path))) {
@@ -336,7 +349,7 @@
         }
 
         std::string strError;
-        if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(),
+        if (!CWalletDB::VerifyEnvironment(walletFile, GetWalletDir().string(),
                                           strError)) {
             return InitError(strError);
         }
@@ -354,7 +367,7 @@
 
         std::string strWarning;
         bool dbV = CWalletDB::VerifyDatabaseFile(
-            walletFile, GetDataDir().string(), strWarning, strError);
+            walletFile, GetWalletDir().string(), strWarning, strError);
         if (!strWarning.empty()) {
             InitWarning(strWarning);
         }
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -21,11 +21,10 @@
 #include "util.h"
 #include "utilmoneystr.h"
 #include "validation.h"
-#include "wallet.h"
 #include "wallet/coincontrol.h"
 #include "wallet/wallet.h"
 #include "wallet/walletdb.h"
-#include "walletdb.h"
+#include "wallet/walletutil.h"
 // Input src/init.h (not wallet/init.h) for StartShutdown
 #include <init.h>
 
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
--- a/src/wallet/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -240,11 +240,11 @@
     static bool IsKeyType(const std::string &strType);
     /* verifies the database environment */
     static bool VerifyEnvironment(const std::string &walletFile,
-                                  const fs::path &dataDir,
+                                  const fs::path &walletDir,
                                   std::string &errorStr);
     /* verifies the database file */
     static bool VerifyDatabaseFile(const std::string &walletFile,
-                                   const fs::path &dataDir,
+                                   const fs::path &walletDir,
                                    std::string &warningStr,
                                    std::string &errorStr);
 
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -836,16 +836,16 @@
 }
 
 bool CWalletDB::VerifyEnvironment(const std::string &walletFile,
-                                  const fs::path &dataDir,
+                                  const fs::path &walletDir,
                                   std::string &errorStr) {
-    return CDB::VerifyEnvironment(walletFile, dataDir, errorStr);
+    return CDB::VerifyEnvironment(walletFile, walletDir, errorStr);
 }
 
 bool CWalletDB::VerifyDatabaseFile(const std::string &walletFile,
-                                   const fs::path &dataDir,
+                                   const fs::path &walletDir,
                                    std::string &warningStr,
                                    std::string &errorStr) {
-    return CDB::VerifyDatabaseFile(walletFile, dataDir, warningStr, errorStr,
+    return CDB::VerifyDatabaseFile(walletFile, walletDir, warningStr, errorStr,
                                    CWalletDB::Recover);
 }
 
diff --git a/src/wallet/walletutil.h b/src/wallet/walletutil.h
new file mode 100644
--- /dev/null
+++ b/src/wallet/walletutil.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2017 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_WALLET_UTIL_H
+#define BITCOIN_WALLET_UTIL_H
+
+#include "util.h"
+
+//! Get the path of the wallet directory.
+fs::path GetWalletDir();
+
+#endif // BITCOIN_WALLET_UTIL_H
diff --git a/src/wallet/walletutil.cpp b/src/wallet/walletutil.cpp
new file mode 100644
--- /dev/null
+++ b/src/wallet/walletutil.cpp
@@ -0,0 +1,22 @@
+// Copyright (c) 2017 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "wallet/walletutil.h"
+
+fs::path GetWalletDir() {
+    fs::path path;
+
+    if (gArgs.IsArgSet("-walletdir")) {
+        path = fs::system_complete(gArgs.GetArg("-walletdir", ""));
+        if (!fs::is_directory(path)) {
+            // If the path specified doesn't exist, we return the deliberately
+            // invalid empty string.
+            path = "";
+        }
+    } else {
+        path = GetDataDir();
+    }
+
+    return path;
+}
diff --git a/test/functional/multiwallet.py b/test/functional/multiwallet.py
--- a/test/functional/multiwallet.py
+++ b/test/functional/multiwallet.py
@@ -47,6 +47,22 @@
         self.assert_start_raises_init_error(
             0, ['-wallet=w12'], 'Error loading wallet w12. -wallet filename must be a regular file.')
 
+        # should not initialize if the specified walletdir does not exist
+        self.assert_start_raises_init_error(
+            0, ['-walletdir=bad'], 'Error: Specified wallet directory "bad" does not exist.')
+
+        # running the node with specified walletdir should only have the default wallet in it
+        os.mkdir(os.path.join(self.options.tmpdir,
+                              'node0', 'regtest', 'walletdir'))
+        self.start_node(0, ['-wallet=w4', '-wallet=w5', '-walletdir=' +
+                            os.path.join(self.options.tmpdir, 'node0', 'regtest', 'walletdir')])
+        assert_equal(set(self.nodes[0].listwallets()), {"w4", "w5"})
+        w5 = self.nodes[0].get_wallet_rpc("w5")
+        w5_info = w5.getwalletinfo()
+        assert_equal(w5_info['immature_balance'], 0)
+
+        self.stop_node(0)
+
         self.start_node(0, self.extra_args[0])
 
         w1 = self.nodes[0].get_wallet_rpc("w1")