diff --git a/Cargo.toml b/Cargo.toml
index 4d0a04365fb24a65359e349a1f37187a6d4fe2e9..a327b5d7861e2659fd5e9013c276e9e3aff9fc02 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,4 +7,7 @@ authors = ["David Mehren <dmehren1@gmail.com>"]
 bv = "0.7"
 bio = "0.19.0"
 id_tree = "1.3.0"
-failure = "0.1.1"
\ No newline at end of file
+failure = "0.1.1"
+serde = "1.0.64"
+serde_derive = "1.0.64"
+bincode = "1.0.0"
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index 2b18f66d49be140b1ffe53d4fae82f93b6bcd201..e21698b57b98d69000c128653471058f68e2a9c3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,6 +3,9 @@ extern crate bv;
 extern crate id_tree;
 #[macro_use]
 extern crate failure;
+#[macro_use]
+extern crate serde_derive;
+extern crate bincode;
 
 pub mod common;
 pub mod trees;
diff --git a/src/trees/bp_tree.rs b/src/trees/bp_tree.rs
index eb4ffcc5f0338a40edfa3583294dad3d6d05cdda..693bce5506e13f8efe65e0228b8e16ec8a9cbe52 100644
--- a/src/trees/bp_tree.rs
+++ b/src/trees/bp_tree.rs
@@ -1,18 +1,29 @@
+use bincode::{deserialize, serialize};
 use bio::data_structures::rank_select::RankSelect;
 use bv::{BitVec, BitsMut};
 use common::succinct_tree::SuccinctTree;
-use failure::Error;
+use failure::{Error, ResultExt};
 use id_tree::Tree;
 use std::fmt;
 use std::fmt::Debug;
 use std::fmt::Formatter;
+use std::fs;
+use std::fs::File;
+use std::io::Write;
 
+#[derive(Serialize, Deserialize)]
 pub struct BPTree {
     bits: BitVec<u8>,
     rankselect: RankSelect,
     rminmax: String,
 }
 
+impl PartialEq for BPTree {
+    fn eq(&self, other: &BPTree) -> bool {
+        self.bits == other.bits
+    }
+}
+
 impl SuccinctTree<BPTree> for BPTree {
     fn is_leaf(&self, index: u64) -> bool {
         unimplemented!()
@@ -64,6 +75,19 @@ impl BPTree {
             rminmax: "foo".to_string(),
         })
     }
+
+    pub fn from_file(path: String) -> Result<BPTree, Error> {
+        let file = fs::read(path).context("Could not read saved tree.")?;
+        let tree: BPTree = deserialize(&file).context("Error while deserializing tree.")?;
+        Ok(tree)
+    }
+
+    pub fn save_to(&self, path: String) -> Result<(), Error> {
+        let encoded = serialize(&self).context("Error while serializing tree.")?;
+        let mut file = File::create(path).context("Could not save tree.")?;
+        file.write_all(&encoded)?;
+        Ok(())
+    }
 }
 
 #[cfg(test)]
@@ -84,7 +108,26 @@ mod tests {
     #[test]
     #[should_panic(expected = "ErrorMessage { msg: \"Bit vector not valid.\" }")]
     fn new_from_bitvec_invalid() {
-        let mut bitvec = BitVec::new_fill(false, 2);
+        let bitvec = BitVec::new_fill(false, 2);
         BPTree::from_bitvec(bitvec.clone()).unwrap();
     }
+
+    #[test]
+    fn save_load() {
+        let tree = BPTree::stub_create();
+        tree.save_to("testdata/bptree.testdata".to_string())
+            .unwrap();
+        let result = BPTree::from_file("testdata/bptree.testdata".to_string()).unwrap();
+        assert_eq!(
+            tree, result,
+            "The loaded tree is not equal to the original one."
+        );
+    }
+
+    #[test]
+    #[should_panic(expected = "Error while deserializing tree.")]
+    fn load_invaild() {
+        BPTree::from_file("testdata/bptree_invalid.testdata".to_string()).unwrap();
+    }
+
 }
diff --git a/testdata/bptree_invalid.testdata b/testdata/bptree_invalid.testdata
new file mode 100644
index 0000000000000000000000000000000000000000..4318da13396d0f974a32b7f727f5bf23ac866417
Binary files /dev/null and b/testdata/bptree_invalid.testdata differ